Cleanup, creating armor enums

This commit is contained in:
seancolyer 2013-10-18 21:18:38 -04:00
parent 8b9d60ba15
commit 7cfa0ab705
12 changed files with 933 additions and 484 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -16,8 +16,7 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
var base64 = require('./base64.js');
var enums = require('../enums.js');
/**
* Finds out which Ascii Armoring type is used. This is an internal function
@ -36,14 +35,14 @@ function get_type(text) {
// Used for multi-part messages, where the armor is split amongst Y
// parts, and this is the Xth part out of Y.
if (splittedtext[1].match(/BEGIN PGP MESSAGE, PART \d+\/\d+/)) {
return 0;
return enums.armor.multipart_section;
} else
// BEGIN PGP MESSAGE, PART X
// Used for multi-part messages, where this is the Xth part of an
// unspecified number of parts. Requires the MESSAGE-ID Armor
// Header to be used.
if (splittedtext[1].match(/BEGIN PGP MESSAGE, PART \d+/)) {
return 1;
return enums.armor.multipart_last;
} else
// BEGIN PGP SIGNATURE
@ -51,25 +50,25 @@ function get_type(text) {
// cleartext signatures. Note that PGP 2.x uses BEGIN PGP MESSAGE
// for detached signatures.
if (splittedtext[1].match(/BEGIN PGP SIGNED MESSAGE/)) {
return 2;
return enums.armor.signed;
} else
// BEGIN PGP MESSAGE
// Used for signed, encrypted, or compressed files.
if (splittedtext[1].match(/BEGIN PGP MESSAGE/)) {
return 3;
return enums.armor.message;
} else
// BEGIN PGP PUBLIC KEY BLOCK
// Used for armoring public keys.
if (splittedtext[1].match(/BEGIN PGP PUBLIC KEY BLOCK/)) {
return 4;
return enums.armor.public_key;
} else
// BEGIN PGP PRIVATE KEY BLOCK
// Used for armoring private keys.
if (splittedtext[1].match(/BEGIN PGP PRIVATE KEY BLOCK/)) {
return 5;
return enums.armor.private_key;
}
}
@ -184,7 +183,7 @@ function createcrc24(input) {
}
for (var j = index; j < input.length; j++) {
crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index++)) & 0xff]
crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index++)) & 0xff];
}
return crc & 0xffffff;
}
@ -198,7 +197,7 @@ function createcrc24(input) {
* and an attribute "openpgp" containing the bytes.
*/
function dearmor(text) {
text = text.replace(/\r/g, '')
text = text.replace(/\r/g, '');
var type = get_type(text);
@ -265,21 +264,21 @@ function dearmor(text) {
function armor(messagetype, data, options, partindex, parttotal) {
var result = "";
switch (messagetype) {
case 0:
case enums.armor.multipart_section:
result += "-----BEGIN PGP MESSAGE, PART " + partindex + "/" + parttotal + "-----\r\n";
result += armor_addheader(options);
result += base64.encode(data);
result += "\r\n=" + getCheckSum(data) + "\r\n";
result += "-----END PGP MESSAGE, PART " + partindex + "/" + parttotal + "-----\r\n";
break;
case 1:
case enums.armor.mutlipart_last:
result += "-----BEGIN PGP MESSAGE, PART " + partindex + "-----\r\n";
result += armor_addheader(options);
result += base64.encode(data);
result += "\r\n=" + getCheckSum(data) + "\r\n";
result += "-----END PGP MESSAGE, PART " + partindex + "-----\r\n";
break;
case 2:
case enums.armor.signed:
result += "\r\n-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: " + data.hash + "\r\n\r\n";
result += data.text.replace(/\n-/g, "\n- -");
result += "\r\n-----BEGIN PGP SIGNATURE-----\r\n";
@ -288,21 +287,21 @@ function armor(messagetype, data, options, partindex, parttotal) {
result += "\r\n=" + getCheckSum(data.openpgp) + "\r\n";
result += "-----END PGP SIGNATURE-----\r\n";
break;
case 3:
case enums.armor.message:
result += "-----BEGIN PGP MESSAGE-----\r\n";
result += armor_addheader(options);
result += base64.encode(data);
result += "\r\n=" + getCheckSum(data) + "\r\n";
result += "-----END PGP MESSAGE-----\r\n";
break;
case 4:
case enums.armor.public_key:
result += "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n";
result += armor_addheader(options);
result += base64.encode(data);
result += "\r\n=" + getCheckSum(data) + "\r\n";
result += "-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n";
break;
case 5:
case enums.armor.private_key:
result += "-----BEGIN PGP PRIVATE KEY BLOCK-----\r\n";
result += armor_addheader(options);
result += base64.encode(data);
@ -317,4 +316,4 @@ function armor(messagetype, data, options, partindex, parttotal) {
module.exports = {
encode: armor,
decode: dearmor
}
};

View File

@ -237,13 +237,22 @@ var enums = {
embedded_signature: 32
},
armor: {
multipart_section: 0,
multipart_last: 1,
signed: 2,
message: 3,
public_key: 4,
private_key: 5
},
// Asserts validity and converts from string/integer to integer.
write: function(type, e) {
if (typeof e == 'number') {
e = this.read(type, e);
}
if (type[e] != undefined) {
if (type[e] !== undefined) {
return type[e];
} else throw new Error('Invalid enum value.');
},

View File

@ -39,7 +39,7 @@ module.exports = function key() {
return this.packets[i];
return null;
}
};
/** Returns all the private and public subkeys
* @returns {openpgp_packet_subkey[]} */
@ -53,19 +53,18 @@ module.exports = function key() {
subkeys.push(this.packets[i]);
return subkeys;
}
};
this.getAllKeys = function() {
return [this.getKey()].concat(this.getSubkeys());
}
};
this.getSigningKey = function() {
var signing = ['rsa_encrypt_sign', 'rsa_sign', 'dsa'];
signing = signing.map(function(s) {
return openpgp.publickey[s];
})
});
var keys = this.getAllKeys();
@ -74,12 +73,12 @@ module.exports = function key() {
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.")
if (pkey === null) {
util.print_error("private key is for encryption only! Cannot create a signature.");
return null;
}
if (pkey.publicKey.publicKeyAlgorithm == 17) {
@ -99,11 +98,11 @@ module.exports = function key() {
// V4: by convention subkeys are prefered for encryption service
// V3: keys MUST NOT have subkeys
var isValidSignKey = function(key) {
return key.algorithm != enums.read(enums.publicKey, enums.publicKey.dsa)
&& key.algorithm != enums.read(enums.publicKey, enums.publicKey.rsa_sign)
return key.algorithm != enums.read(enums.publicKey, enums.publicKey.dsa) && key.algorithm != enums.read(enums.publicKey,
enums.publicKey.rsa_sign);
//TODO verify key
//&& keys.verifyKey()
}
};
var subKeys = this.getSubkeys();
for (var j = 0; j < subKeys.length; j++) {
@ -117,19 +116,17 @@ module.exports = function key() {
return primaryKey;
}
return null;
}
};
this.decrypt = function(passphrase) {
var keys = this.getAllKeys();
for (var i in keys)
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);
}
};
// TODO need to implement this
@ -139,4 +136,4 @@ module.exports = function key() {
}
}
};

View File

@ -104,12 +104,12 @@ function _openpgp() {
symEncryptedPacket.encrypt(enums.read(enums.symmetric, config.encryption_cipher), sessionKey);
packetList.push(symEncryptedPacket);
var armored = armor.encode(3, packetList.write(), config);
var armored = armor.encode(enums.armor.message, packetList.write(), config);
return armored;
}
function encryptAndSignMessage(publicKeyPacketlist, privateKeyPacketlist, message) {
function encryptAndSignMessage(publicKeys, privateKeyPacketlist, message) {
}
@ -129,6 +129,20 @@ function _openpgp() {
}
/**
* TODO: update this doc
* generates a new key pair for openpgp. Beta stage. Currently only
* supports RSA keys, and no subkeys.
* @param {Integer} keyType to indicate what type of key to make.
* RSA is 1. Follows algorithms outlined in OpenPGP.
* @param {Integer} numBits number of bits for the key creation. (should
* be 1024+, generally)
* @param {String} userId assumes already in form of "User Name
* <username@email.com>"
* @param {String} passphrase The passphrase used to encrypt the resulting private key
* @return {Object} {privateKey: [openpgp_msg_privatekey],
* privateKeyArmored: [string], publicKeyArmored: [string]}
*/
function generateKeyPair(keyType, numBits, userId, passphrase) {
debugger;
var packetlist = new packet.list();
@ -145,7 +159,7 @@ function _openpgp() {
dataToSign.userid = userIdPacket;
dataToSign.key = secretKeyPacket;
var signaturePacket = new packet.signature();
signaturePacket.issuerKeyId = secretKeyPacket.getKeyId();
signaturePacket.issuerKeyId = secretKeyPacket.getKeyId().write();
signaturePacket.signatureType = enums.signature.cert_generic;
signaturePacket.publicKeyAlgorithm = keyType;
//TODO we should load preferred hash from config, or as input to this function
@ -161,7 +175,7 @@ function _openpgp() {
dataToSign.key = secretKeyPacket;
dataToSign.bind = secretSubkeyPacket;
var subkeySignaturePacket = new packet.signature();
subkeySignaturePacket.issuerKeyId = secretSubkeyPacket.getKeyId();
subkeySignaturePacket.issuerKeyId = secretSubkeyPacket.getKeyId().write();
subkeySignaturePacket.signatureType = enums.signature.subkey_binding;
subkeySignaturePacket.publicKeyAlgorithm = keyType;
//TODO we should load preferred hash from config, or as input to this function
@ -174,7 +188,8 @@ function _openpgp() {
packetlist.push(secretSubkeyPacket);
packetlist.push(subkeySignaturePacket);
var armored = armor.encode(5, packetlist.write(), this.config);
var armored = armor.encode(enums.armor.private_key, packetlist.write(), this.config);
return armored;
}
/**
@ -309,53 +324,6 @@ function _openpgp() {
return armor.encode(2, result, null, null);
}
/**
* generates a new key pair for openpgp. Beta stage. Currently only
* supports RSA keys, and no subkeys.
* @param {Integer} keyType to indicate what type of key to make.
* RSA is 1. Follows algorithms outlined in OpenPGP.
* @param {Integer} numBits number of bits for the key creation. (should
* be 1024+, generally)
* @param {String} userId assumes already in form of "User Name
* <username@email.com>"
* @param {String} passphrase The passphrase used to encrypt the resulting private key
* @return {Object} {privateKey: [openpgp_msg_privatekey],
* privateKeyArmored: [string], publicKeyArmored: [string]}
*/
function generate_key_pair(keyType, numBits, userId, passphrase) {
var userIdPacket = new openpgp_packet_userid();
var userIdString = userIdPacket.write_packet(userId);
var keyPair = openpgp_crypto_generateKeyPair(keyType, numBits, passphrase, openpgp.config.config.prefer_hash_algorithm,
3);
var privKeyString = keyPair.privateKey;
var privKeyPacket = new openpgp_packet_keymaterial().read_priv_key(privKeyString.string, 3, privKeyString.string.length);
if (!privKeyPacket.decryptSecretMPIs(passphrase))
util.print_error('Issue creating key. Unable to read resulting private key');
var privKey = new openpgp_msg_privatekey();
privKey.privateKeyPacket = privKeyPacket;
privKey.getPreferredSignatureHashAlgorithm = function() {
return openpgp.config.config.prefer_hash_algorithm
}; //need to override this to solve catch 22 to generate signature. 8 is value for SHA256
var publicKeyString = privKey.privateKeyPacket.publicKey.data;
var hashData = String.fromCharCode(0x99) + String.fromCharCode(((publicKeyString.length) >> 8) & 0xFF) + String.fromCharCode((
publicKeyString.length) & 0xFF) + publicKeyString + String.fromCharCode(0xB4) +
String.fromCharCode((userId.length) >> 24) + String.fromCharCode(((userId.length) >> 16) & 0xFF) + String.fromCharCode(((
userId.length) >> 8) & 0xFF) + String.fromCharCode((userId.length) & 0xFF) + userId;
var signature = new openpgp_packet_signature();
signature = signature.write_message_signature(16, hashData, privKey);
var publicArmored = armor.encode(4, keyPair.publicKey.string + userIdString + signature.openpgp);
var privArmored = armor.encode(5, privKeyString.string + userIdString + signature.openpgp);
return {
privateKey: privKey,
privateKeyArmored: privArmored,
publicKeyArmored: publicArmored
};
}
this.generateKeyPair = generateKeyPair;
this.write_signed_message = write_signed_message;
this.write_signed_and_encrypted_message = write_signed_and_encrypted_message;

View File

@ -73,7 +73,7 @@ var keyring = function() {
}
function idPacketCheck(packet, id) {
if (packet.getKeyId && packet.getKeyId() == id) {
if (packet.getKeyId && packet.getKeyId().write() == id) {
return true;
}
return false;

View File

@ -91,7 +91,7 @@ module.exports = function packet_one_pass_signature() {
result += String.fromCharCode(enums.write(enums.signature, type));
result += String.fromCharCode(enums.write(enums.hash, this.hashAlgorithm));
result += String.fromCharCode(enums.write(enums.publicKey, privatekey.algorithm));
result += privatekey.getKeyId();
result += privatekey.getKeyId().write();
if (nested)
result += String.fromCharCode(0);
else

View File

@ -14,8 +14,6 @@ module.exports = function packetlist() {
* @type {Integer} */
this.length = 0;
/**
* Reads a stream of binary data and interprents it as a list of packets.
* @param {openpgp_bytearray} An array of bytes.

View File

@ -197,7 +197,7 @@ module.exports = function packet_signature() {
var creationTimeSubpacket = write_sub_packet(enums.signatureSubpacket.signature_creation_time,
util.writeDate(new Date()));
var issuerSubpacket = write_sub_packet(enums.signatureSubpacket.issuer, key.getKeyId());
var issuerSubpacket = write_sub_packet(enums.signatureSubpacket.issuer, key.getKeyId().write());
// Add subpackets here
result += util.writeNumber(creationTimeSubpacket.length + issuerSubpacket.length, 2);

View File

@ -4,13 +4,15 @@ unit.register("Encryption/decryption", function() {
var openpgp = require('../../');
var keyring = require('../../src/openpgp.keyring.js');
var result = [];
var testHelper = function(passphrase, userid, message) {
var key = openpgp.generateKeyPair(openpgp.enums.publicKey.rsa_encrypt_sign, 512,
'Test McTestington <test@example.com>', 'hello world');
userid, message, passphrase);
var info = '\npassphrase: ' + passphrase + '\n'
+ 'userid: ' + userid + '\n'
+ 'message: ' + message;
var keyPacketlist = openpgp.readArmoredPackets(key);
if(!priv_key.decryptSecretMPIs(passphrase)) {
return new test_result('Generating a decryptable private key failed'
+ info,
@ -20,7 +22,7 @@ unit.register("Encryption/decryption", function() {
var encrypted = openpgp.write_signed_and_encrypted_message(priv_key,
pub_key, message);
openpgp.keyring.importPublicKey(key.publicKeyArmored)
openpgp.keyring.importPublicKey(key.publicKeyArmored);
var msg = openpgp.read_message(encrypted);
@ -29,13 +31,13 @@ unit.register("Encryption/decryption", function() {
// Find the private (sub)key for the session key of the message
for (var i = 0; i< msg[0].sessionKeys.length; i++) {
if (priv_key.privateKeyPacket.publicKey.getKeyId() == msg[0].sessionKeys[i].keyId.bytes) {
if (priv_key.privateKeyPacket.publicKey.getKeyId().write() == msg[0].sessionKeys[i].keyId.bytes) {
keymat = { key: priv_key, keymaterial: priv_key.privateKeyPacket};
sesskey = msg[0].sessionKeys[i];
break;
}
for (var j = 0; j < priv_key.subKeys.length; j++) {
if (priv_key.subKeys[j].publicKey.getKeyId() == msg[0].sessionKeys[i].keyId.bytes) {
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;
@ -54,11 +56,11 @@ unit.register("Encryption/decryption", function() {
} else {
return new test_result("No private key found!" + info, false);
}
return new test_result(message + ' == ' + decrypted + info, message == decrypted);
};
result.push(new test_result(message + ' == ' + decrypted + info, message == decrypted));
//result.push(test('password', 'Test McTestington <test@example.com>', 'hello world'));
//result.push(test('●●●●', '♔♔♔♔ <test@example.com>', 'łäóć'));
result.push(testHelper('password', 'Test McTestington <test@example.com>', 'hello world'));
result.push(testHelper('●●●●', '♔♔♔♔ <test@example.com>', 'łäóć'));
return result;
});

File diff suppressed because one or more lines are too long