Started cleaning up the public API/Keyring to use the "packetlist"

concept. More cleanup still to do, also need to determine best way to
submodule keyring. Ripping out previous packet.io addition because it
isn't needed/ goes against packetlist.
This commit is contained in:
seancolyer 2013-10-06 21:40:31 -04:00
parent 766d3e34fe
commit 30d2c38f00
9 changed files with 1576 additions and 2570 deletions

File diff suppressed because one or more lines are too long

View File

@ -259,7 +259,7 @@ module.exports = {
text = text.join(''); text = text.join('');
text = text.substring(n, ciphertext.length - block_size - 2); text = text.substring(n, ciphertext.length - block_size - 2 + n);
return text; return text;

View File

@ -47,83 +47,6 @@ function _openpgp () {
this.keyring.init(); this.keyring.init();
} }
/**
* reads several publicKey objects from a ascii armored
* representation an returns openpgp_msg_publickey packets
* @param {String} armoredText OpenPGP armored text containing
* the public key(s)
* @return {openpgp_msg_publickey[]} on error the function
* returns null
*/
function read_publicKey(armoredText) {
var mypos = 0;
var publicKeys = [];
var publicKeyCount = 0;
var input = armor.decode(armoredText.replace(/\r/g,'')).openpgp;
var l = input.length;
while (mypos != input.length) {
var first_packet = packet.io.read(input, mypos, l);
// public key parser
if (input[mypos].charCodeAt() == 0x99 || first_packet.tagType == 6) {
publicKeys[publicKeyCount] = new openpgp_msg_publickey();
publicKeys[publicKeyCount].header = input.substring(mypos,mypos+3);
if (input[mypos].charCodeAt() == 0x99) {
// parse the length and read a tag6 packet
mypos++;
var l = (input[mypos++].charCodeAt() << 8)
| input[mypos++].charCodeAt();
publicKeys[publicKeyCount].publicKeyPacket = new openpgp_packet_keymaterial();
publicKeys[publicKeyCount].publicKeyPacket.header = publicKeys[publicKeyCount].header;
publicKeys[publicKeyCount].publicKeyPacket.read_tag6(input, mypos, l);
mypos += publicKeys[publicKeyCount].publicKeyPacket.packetLength;
mypos += publicKeys[publicKeyCount].read_nodes(publicKeys[publicKeyCount].publicKeyPacket, input, mypos, (input.length - mypos));
} else {
publicKeys[publicKeyCount] = new openpgp_msg_publickey();
publicKeys[publicKeyCount].publicKeyPacket = first_packet;
mypos += first_packet.headerLength+first_packet.packetLength;
mypos += publicKeys[publicKeyCount].read_nodes(first_packet, input, mypos, input.length -mypos);
}
} else {
util.print_error("no public key found!");
return null;
}
publicKeys[publicKeyCount].data = input.substring(0,mypos);
publicKeyCount++;
}
return publicKeys;
}
/**
* reads several privateKey objects from a ascii armored
* representation an returns openpgp_msg_privatekey objects
* @param {String} armoredText OpenPGP armored text containing
* the private key(s)
* @return {openpgp_msg_privatekey[]} on error the function
* returns null
*/
function read_privateKey(armoredText) {
var privateKeys = [];
var privateKeyCount = 0;
var mypos = 0;
var input = armor.decode(armoredText.replace(/\r/g,'')).openpgp;
var l = input.length;
while (mypos != input.length) {
var first_packet = packet.io.read(input, mypos, l);
if (first_packet.tagType == 5) {
privateKeys[privateKeys.length] = new openpgp_msg_privatekey();
mypos += first_packet.headerLength+first_packet.packetLength;
mypos += privateKeys[privateKeyCount].read_nodes(first_packet, input, mypos, l);
// other blocks
} else {
util.print_error('no block packet found!');
return null;
}
privateKeys[privateKeyCount].data = input.substring(0,mypos);
privateKeyCount++;
}
return privateKeys;
}
/** /**
* reads message packets out of an OpenPGP armored text and * reads message packets out of an OpenPGP armored text and
* returns an array of message objects * returns an array of message objects
@ -131,16 +54,10 @@ function _openpgp () {
* @return {openpgp_msg_message[]} on error the function * @return {openpgp_msg_message[]} on error the function
* returns null * returns null
*/ */
function read_message(armoredText) { function readArmoredPackets(armoredText) {
var dearmored; //TODO how do we want to handle bad text? Exception throwing
try{ var input = armor.decode(armoredText.replace(/\r/g,'')).openpgp;
dearmored = armor.decode(armoredText.replace(/\r/g,'')); return readDearmoredPackets(input);
}
catch(e){
util.print_error('no message found!');
return null;
}
return read_messages_dearmored(dearmored);
} }
/** /**
@ -152,142 +69,30 @@ function _openpgp () {
* @return {openpgp_msg_message[]} on error the function * @return {openpgp_msg_message[]} on error the function
* returns null * returns null
*/ */
function read_messages_dearmored(input){ function readDearmoredPackets(input){
var messageString = input.openpgp; var packetList = new packet.list();
var signatureText = input.text; //text to verify signatures against. Modified by Tag11. packetList.read(input);
var messages = []; return packetList;
var messageCount = 0;
var mypos = 0;
var l = messageString.length;
while (mypos < messageString.length) {
var first_packet = packet.io.read(messageString, mypos, l);
if (!first_packet) {
break;
}
// public key parser (definition from the standard:)
// OpenPGP Message :- Encrypted Message | Signed Message |
// Compressed Message | Literal Message.
// Compressed Message :- Compressed Data Packet.
//
// Literal Message :- Literal Data Packet.
//
// ESK :- Public-Key Encrypted Session Key Packet |
// Symmetric-Key Encrypted Session Key Packet.
//
// ESK Sequence :- ESK | ESK Sequence, ESK.
//
// Encrypted Data :- Symmetrically Encrypted Data Packet |
// Symmetrically Encrypted Integrity Protected Data Packet
//
// Encrypted Message :- Encrypted Data | ESK Sequence, Encrypted Data.
//
// One-Pass Signed Message :- One-Pass Signature Packet,
// OpenPGP Message, Corresponding Signature Packet.
// Signed Message :- Signature Packet, OpenPGP Message |
// One-Pass Signed Message.
if (first_packet.tagType == 1 ||
(first_packet.tagType == 2 && first_packet.signatureType < 16) ||
first_packet.tagType == 3 ||
first_packet.tagType == 4 ||
first_packet.tagType == 8 ||
first_packet.tagType == 9 ||
first_packet.tagType == 10 ||
first_packet.tagType == 11 ||
first_packet.tagType == 18 ||
first_packet.tagType == 19) {
messages[messages.length] = new openpgp_msg_message();
messages[messageCount].messagePacket = first_packet;
messages[messageCount].type = input.type;
// Encrypted Message
if (first_packet.tagType == 9 ||
first_packet.tagType == 1 ||
first_packet.tagType == 3 ||
first_packet.tagType == 18) {
if (first_packet.tagType == 9) {
util.print_error("unexpected openpgp packet");
break;
} else if (first_packet.tagType == 1) {
util.print_debug("session key found:\n "+first_packet.toString());
var issessionkey = true;
messages[messageCount].sessionKeys = new Array();
var sessionKeyCount = 0;
while (issessionkey) {
messages[messageCount].sessionKeys[sessionKeyCount] = first_packet;
mypos += first_packet.packetLength + first_packet.headerLength;
l -= (first_packet.packetLength + first_packet.headerLength);
first_packet = packet.io.read(messageString, mypos, l);
if (first_packet.tagType != 1 && first_packet.tagType != 3)
issessionkey = false;
sessionKeyCount++;
}
if (first_packet.tagType == 18 || first_packet.tagType == 9) {
util.print_debug("encrypted data found:\n "+first_packet.toString());
messages[messageCount].encryptedData = first_packet;
mypos += first_packet.packetLength+first_packet.headerLength;
l -= (first_packet.packetLength+first_packet.headerLength);
messageCount++;
} else {
util.print_debug("something is wrong: "+first_packet.tagType);
} }
} else if (first_packet.tagType == 18) { function encryptMessage(publicKeyPacketlist, message) {
util.print_debug("symmetric encrypted data");
break;
}
} else
if (first_packet.tagType == 2 && first_packet.signatureType < 3) {
// Signed Message
mypos += first_packet.packetLength + first_packet.headerLength;
l -= (first_packet.packetLength + first_packet.headerLength);
messages[messageCount].text = signatureText;
messages[messageCount].signature = first_packet;
messageCount++;
} else
// Signed Message
if (first_packet.tagType == 4) {
//TODO: Implement check
mypos += first_packet.packetLength + first_packet.headerLength;
l -= (first_packet.packetLength + first_packet.headerLength);
} else
if (first_packet.tagType == 8) {
// Compressed Message
mypos += first_packet.packetLength + first_packet.headerLength;
l -= (first_packet.packetLength + first_packet.headerLength);
var decompressedText = first_packet.decompress();
messages = messages.concat(openpgp.read_messages_dearmored({text: decompressedText, openpgp: decompressedText}));
} else
// Marker Packet (Obsolete Literal Packet) (Tag 10)
// "Such a packet MUST be ignored when received." see http://tools.ietf.org/html/rfc4880#section-5.8
if (first_packet.tagType == 10) {
// reset messages
messages.length = 0;
// continue with next packet
mypos += first_packet.packetLength + first_packet.headerLength;
l -= (first_packet.packetLength + first_packet.headerLength);
} else
if (first_packet.tagType == 11) {
// Literal Message -- work is already done in packet.io.read
mypos += first_packet.packetLength + first_packet.headerLength;
l -= (first_packet.packetLength + first_packet.headerLength);
signatureText = first_packet.data;
messages[messageCount].data = first_packet.data;
messageCount++;
} else
if (first_packet.tagType == 19) {
// Modification Detect Code
mypos += first_packet.packetLength + first_packet.headerLength;
l -= (first_packet.packetLength + first_packet.headerLength);
}
} else {
util.print_error('no message found!');
return null;
}
} }
return messages; function encryptAndSignMessage(publicKeyPacketlist, privateKeyPacketlist, message) {
}
function decryptMessage(privateKeyPacketlist, messagePacketlist) {
}
function decryptAndVerifyMessage(privateKeyPacketlist, publicKeyPacketlist, messagePacketlist) {
}
function verifyMessage(publicKeyPacketlist, messagePacketlist) {
} }
/** /**
@ -454,10 +259,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.write_encrypted_message = write_encrypted_message; this.write_encrypted_message = write_encrypted_message;
this.read_message = read_message; this.readArmoredPackets = readArmoredPackets;
this.read_messages_dearmored = read_messages_dearmored; this.readDearmoredPackets = readDearmoredPackets;
this.read_publicKey = read_publicKey;
this.read_privateKey = read_privateKey;
this.init = init; this.init = init;
} }

View File

@ -15,11 +15,17 @@
// 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 The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. * @classdesc The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage.
*/ */
function openpgp_keyring() { var keyring = function() {
this.armoredPacketlists = [];
this.parsedPacketlists = [];
/** /**
* Initialization routine for the keyring. This method reads the * Initialization routine for the keyring. This method reads the
@ -27,85 +33,70 @@ function openpgp_keyring() {
* This method is called by openpgp.init(). * This method is called by openpgp.init().
*/ */
function init() { function init() {
var sprivatekeys = JSON.parse(window.localStorage.getItem("privatekeys")); var armoredPacketlists = JSON.parse(window.localStorage.getItem("armoredPacketlists"));
var spublickeys = JSON.parse(window.localStorage.getItem("publickeys")); if (armoredPacketlists === null || armoredPacketlists.length === 0) {
if (sprivatekeys == null || sprivatekeys.length == 0) { armoredPacketlists = [];
sprivatekeys = new Array();
} }
this.armoredPacketlists = armoredPacketlists;
if (spublickeys == null || spublickeys.length == 0) { var packetlist;
spublickeys = new Array(); for (var i = 0; i < armoredPacketlists.length; i++) {
} packetlist = new packet.list();
this.publicKeys = new Array(); packetlist.read(armoredPacketlists[i]);
this.privateKeys = new Array(); this.parsedPacketlists.push(packetlist);
var k = 0;
for (var i =0; i < sprivatekeys.length; i++) {
var r = openpgp.read_privateKey(sprivatekeys[i]);
this.privateKeys[k] = { armored: sprivatekeys[i], obj: r[0], keyId: r[0].getKeyId()};
k++;
}
k = 0;
for (var i =0; i < spublickeys.length; i++) {
var r = openpgp.read_publicKey(spublickeys[i]);
if (r[0] != null) {
this.publicKeys[k] = { armored: spublickeys[i], obj: r[0], keyId: r[0].getKeyId()};
k++;
}
} }
} }
this.init = init; this.init = init;
/**
* Checks if at least one private key is in the keyring
* @return {Boolean} True if there are private keys, else false.
*/
function hasPrivateKey() {
return this.privateKeys.length > 0;
}
this.hasPrivateKey = hasPrivateKey;
/** /**
* Saves the current state of the keyring to HTML5 local storage. * Saves the current state of the keyring to HTML5 local storage.
* The privateKeys array and publicKeys array gets Stringified using JSON * The privateKeys array and publicKeys array gets Stringified using JSON
*/ */
function store() { function store() {
var priv = new Array(); window.localStorage.setItem("armoredPacketlists", JSON.stringify(this.armoredPacketlists));
for (var i = 0; i < this.privateKeys.length; i++) {
priv[i] = this.privateKeys[i].armored;
}
var pub = new Array();
for (var i = 0; i < this.publicKeys.length; i++) {
pub[i] = this.publicKeys[i].armored;
}
window.localStorage.setItem("privatekeys",JSON.stringify(priv));
window.localStorage.setItem("publickeys",JSON.stringify(pub));
} }
this.store = store; this.store = store;
function checkForEmailAndPacketMatch(email, packetType){
email = email.toLowerCase();
var results = [];
var packetlist;
var packet;
var packetEmail;
var emailMatch;
var packetMatch;
for (var p = 0; p < this.parsedPacketlists.length; p++) {
emailMatch = false;
packetMatch = false;
packetlist = this.parsedPacketlists[p];
for (var l = 0; l < packetlist.length; l++) {
packet = packetlist[l];
if (packet.tag == enums.packet.userid) {
packetEmail = packet.userid;
//we need to get just the email from the userid packet
packetEmail = packetEmail.split('<')[1].split('<')[0].trim.toLowerCase();
if (packetEmail == email) {
emailMatch = true;
}
}
if (packet.tag == packetType) {
packetMatch = true;
}
}
if (packetMatch && emailMatch) {
results.push(packetlist);
}
}
return results;
}
/** /**
* searches all public keys in the keyring matching the address or address part of the user ids * searches all public keys in the keyring matching the address or address part of the user ids
* @param {String} email_address * @param {String} email_address
* @return {openpgp_msg_publickey[]} The public keys associated with provided email address. * @return {openpgp_msg_publickey[]} The public keys associated with provided email address.
*/ */
function getPublicKeyForAddress(email_address) { function getPublicKeyForAddress(email) {
var results = new Array(); return checkForEmailAndPacketMatch(email, enums.packet.public_key);
var spl = email_address.split("<");
var email = "";
if (spl.length > 1) {
email = spl[1].split(">")[0];
} else {
email = email_address.trim();
}
email = email.toLowerCase();
if(!util.emailRegEx.test(email)){
return results;
}
for (var i =0; i < this.publicKeys.length; i++) {
for (var j = 0; j < this.publicKeys[i].obj.userIds.length; j++) {
if (this.publicKeys[i].obj.userIds[j].text.toLowerCase().indexOf(email) >= 0)
results[results.length] = this.publicKeys[i];
}
}
return results;
} }
this.getPublicKeyForAddress = getPublicKeyForAddress; this.getPublicKeyForAddress = getPublicKeyForAddress;
@ -115,108 +106,39 @@ function openpgp_keyring() {
* @return {openpgp_msg_privatekey[]} private keys found * @return {openpgp_msg_privatekey[]} private keys found
*/ */
function getPrivateKeyForAddress(email_address) { function getPrivateKeyForAddress(email_address) {
var results = new Array(); return checkForEmailAndPacketMatch(email, enums.packet.secret_key);
var spl = email_address.split("<");
var email = "";
if (spl.length > 1) {
email = spl[1].split(">")[0];
} else {
email = email_address.trim();
} }
email = email.toLowerCase();
if(!util.emailRegEx.test(email)){
return results;
}
for (var i =0; i < this.privateKeys.length; i++) {
for (var j = 0; j < this.privateKeys[i].obj.userIds.length; j++) {
if (this.privateKeys[i].obj.userIds[j].text.toLowerCase().indexOf(email) >= 0)
results[results.length] = this.privateKeys[i];
}
}
return results;
}
this.getPrivateKeyForAddress = getPrivateKeyForAddress; this.getPrivateKeyForAddress = getPrivateKeyForAddress;
/** /**
* Searches the keyring for public keys having the specified key id * Searches the keyring for public keys having the specified key id
* @param {String} keyId provided as string of hex number (lowercase) * @param {String} keyId provided as string of hex number (lowercase)
* @return {openpgp_msg_privatekey[]} public keys found * @return {openpgp_msg_privatekey[]} public keys found
*/ */
function getPublicKeysForKeyId(keyId) { function getPacketlistForKeyId(keyId) {
var result = new Array();
for (var i=0; i < this.publicKeys.length; i++) {
var key = this.publicKeys[i];
if (keyId == key.obj.getKeyId())
result[result.length] = key;
else if (key.obj.subKeys != null) {
for (var j=0; j < key.obj.subKeys.length; j++) {
var subkey = key.obj.subKeys[j];
if (keyId == subkey.getKeyId()) {
result[result.length] = {
obj: key.obj.getSubKeyAsKey(j),
keyId: subkey.getKeyId()
} }
} this.getPacketlistForKeyId = getPacketlistForKeyId;
}
}
}
return result;
}
this.getPublicKeysForKeyId = getPublicKeysForKeyId;
/** /**
* Searches the keyring for private keys having the specified key id * TODO test
* @param {String} keyId 8 bytes as string containing the key id to look for * Imports a packet list (public or private key block) from an ascii armored message
* @return {openpgp_msg_privatekey[]} private keys found * @param {String} armored message to read the packets/key from
*/ */
function getPrivateKeyForKeyId(keyId) { function importPacketlist (armored) {
var result = new Array(); this.armoredPacketlists.push(armored);
for (var i=0; i < this.privateKeys.length; i++) {
if (keyId == this.privateKeys[i].obj.getKeyId()) { var dearmored = armor.decode(armored.replace(/\r/g,'')).openpgp;
result[result.length] = { key: this.privateKeys[i], keymaterial: this.privateKeys[i].obj.privateKeyPacket};
} packetlist = new packet.list();
if (this.privateKeys[i].obj.subKeys != null) { packetlist.read(dearmored);
var subkeyids = this.privateKeys[i].obj.getSubKeyIds(); this.parsedPacketlists.push(packetlist);
for (var j=0; j < subkeyids.length; j++)
if (keyId == util.hexstrdump(subkeyids[j])) {
result[result.length] = { key: this.privateKeys[i], keymaterial: this.privateKeys[i].obj.subKeys[j]};
}
}
}
return result;
}
this.getPrivateKeyForKeyId = getPrivateKeyForKeyId;
/**
* Imports a public key from an exported ascii armored message
* @param {String} armored_text PUBLIC KEY BLOCK message to read the public key from
*/
function importPublicKey (armored_text) {
var result = openpgp.read_publicKey(armored_text);
for (var i = 0; i < result.length; i++) {
this.publicKeys[this.publicKeys.length] = {armored: armored_text, obj: result[i], keyId: result[i].getKeyId()};
}
return true; return true;
} }
this.importPacketlist = importPacketlist;
/** /**
* Imports a private key from an exported ascii armored message * TODO
* @param {String} armored_text PRIVATE KEY BLOCK message to read the private key from
*/
function importPrivateKey (armored_text, password) {
var result = openpgp.read_privateKey(armored_text);
if(!result[0].decryptSecretMPIs(password))
return false;
for (var i = 0; i < result.length; i++) {
this.privateKeys[this.privateKeys.length] = {armored: armored_text, obj: result[i], keyId: result[i].getKeyId()};
}
return true;
}
this.importPublicKey = importPublicKey;
this.importPrivateKey = importPrivateKey;
/**
* returns the openpgp_msg_privatekey representation of the public key at public key ring index * returns the openpgp_msg_privatekey representation of the public key at public key ring index
* @param {Integer} index the index of the public key within the publicKeys array * @param {Integer} index the index of the public key within the publicKeys array
* @return {openpgp_msg_privatekey} the public key object * @return {openpgp_msg_privatekey} the public key object
@ -226,8 +148,8 @@ function openpgp_keyring() {
} }
this.exportPublicKey = exportPublicKey; this.exportPublicKey = exportPublicKey;
/** /**
* TODO
* Removes a public key from the public key keyring at the specified index * Removes a public key from the public key keyring at the specified index
* @param {Integer} index the index of the public key within the publicKeys array * @param {Integer} index the index of the public key within the publicKeys array
* @return {openpgp_msg_privatekey} The public key object which has been removed * @return {openpgp_msg_privatekey} The public key object which has been removed
@ -239,26 +161,6 @@ function openpgp_keyring() {
} }
this.removePublicKey = removePublicKey; this.removePublicKey = removePublicKey;
/** };
* returns the openpgp_msg_privatekey representation of the private key at private key ring index
* @param {Integer} index the index of the private key within the privateKeys array
* @return {openpgp_msg_privatekey} the private key object
*/
function exportPrivateKey(index) {
return this.privateKeys[index];
}
this.exportPrivateKey = exportPrivateKey;
/** module.exports = new keyring();
* Removes a private key from the private key keyring at the specified index
* @param {Integer} index the index of the private key within the privateKeys array
* @return {openpgp_msg_privatekey} The private key object which has been removed
*/
function removePrivateKey(index) {
var removed = this.privateKeys.splice(index,1);
this.store();
return removed;
}
this.removePrivateKey = removePrivateKey;
}

View File

@ -3,7 +3,6 @@ var enums = require('../enums.js');
module.exports = { module.exports = {
list: require('./packetlist.js'), list: require('./packetlist.js'),
io: require('./packet.js')
}; };
var packets = require('./all_packets.js'); var packets = require('./all_packets.js');

View File

@ -375,7 +375,7 @@ module.exports = function packet_signature() {
switch(type) { switch(type) {
case t.binary: case t.binary:
return data.literal.getBytes(); return data.getBytes();
case t.text: case t.text:
return this.toSign(t.binary, data) return this.toSign(t.binary, data)

View File

@ -17,18 +17,16 @@
var Util = function() { var Util = function() {
this.readNumber = function (bytes) { this.readNumber = function (bytes) {
var n = 0; var n = 0;
for(var i = 0; i < bytes.length; i++) { for(var i = 0; i < bytes.length; i++) {
n <<= 8; n <<= 8;
n += bytes[i].charCodeAt() n += bytes[i].charCodeAt();
} }
return n; return n;
} };
this.writeNumber = function(n, bytes) { this.writeNumber = function(n, bytes) {
var b = ''; var b = '';
@ -37,7 +35,7 @@ var Util = function() {
} }
return b; return b;
} };
@ -46,13 +44,13 @@ var Util = function() {
var d = new Date(); var d = new Date();
d.setTime(n * 1000); d.setTime(n * 1000);
return d; return d;
} };
this.writeDate = function(time) { this.writeDate = function(time) {
var numeric = Math.round(time.getTime() / 1000); var numeric = Math.round(time.getTime() / 1000);
return this.writeNumber(numeric, 4); return this.writeNumber(numeric, 4);
} };
this.emailRegEx = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/; this.emailRegEx = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/;
@ -333,6 +331,7 @@ var Util = function() {
} }
return "unknown"; return "unknown";
}; };
}; };
/** /**

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 result = []; var result = [];
debugger; var priv_key = openpgp.readArmoredPackets([
var priv_key = openpgp.read_privateKey([
'-----BEGIN PGP PRIVATE KEY BLOCK-----', '-----BEGIN PGP PRIVATE KEY BLOCK-----',
'Version: GnuPG v1.4.11 (GNU/Linux)', 'Version: GnuPG v1.4.11 (GNU/Linux)',
'', '',
@ -33,7 +33,7 @@ unit.register("Testing of binary signature checking", function() {
'=LSrW', '=LSrW',
'-----END PGP PRIVATE KEY BLOCK-----' '-----END PGP PRIVATE KEY BLOCK-----'
].join("\n")); ].join("\n"));
var pub_key = openpgp.read_publicKey( var pub_key = openpgp.readArmoredPackets(
[ '-----BEGIN PGP PUBLIC KEY BLOCK-----', [ '-----BEGIN PGP PUBLIC KEY BLOCK-----',
'Version: GnuPG v1.4.11 (GNU/Linux)', 'Version: GnuPG v1.4.11 (GNU/Linux)',
'', '',
@ -52,7 +52,7 @@ unit.register("Testing of binary signature checking", function() {
'=b2Ln', '=b2Ln',
'-----END PGP PUBLIC KEY BLOCK-----' '-----END PGP PUBLIC KEY BLOCK-----'
].join("\n")); ].join("\n"));
var msg = openpgp.read_message([ var msg = openpgp.readArmoredPackets([
'-----BEGIN PGP MESSAGE-----', '-----BEGIN PGP MESSAGE-----',
'Version: GnuPG v1.4.11 (GNU/Linux)', 'Version: GnuPG v1.4.11 (GNU/Linux)',
'', '',
@ -69,17 +69,18 @@ unit.register("Testing of binary signature checking", function() {
'=4iGt', '=4iGt',
'-----END PGP MESSAGE-----' '-----END PGP MESSAGE-----'
].join("\n")); ].join("\n"));
priv_key[0].subKeys[0].decryptSecretMPIs("abcd"); //TODO need both?
var ret = msg[0].decryptAndVerifySignature( priv_key[0].decrypt("abcd");
{ key: priv_key[0], keymaterial: priv_key[0].subKeys[0]}, priv_key[3].decrypt("abcd");
msg[0].sessionKeys[0], msg[0].decrypt(priv_key[3]);
[{obj:pub_key[0], keyId: pub_key[0].getKeyId()}]); msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
result[0] = new test_result("Testing signature checking on CAST5-enciphered message", msg[1].packets[2].verify(pub_key[0], msg[1].packets[1]);
ret.validSignatures[0] == true); result[0] = new unit.result("Testing signature checking on CAST5-enciphered message",
msg[1].packets[2].verified === true);
// 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.read_privateKey([ var priv_key_gnupg_ext = openpgp.readArmoredPackets([
'-----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,19 +108,16 @@ unit.register("Testing of binary signature checking", function() {
'=GQsY', '=GQsY',
'-----END PGP PRIVATE KEY BLOCK-----', '-----END PGP PRIVATE KEY BLOCK-----',
].join("\n")); ].join("\n"));
priv_key_gnupg_ext[0].subKeys[0].decryptSecretMPIs("abcd"); priv_key_gnupg_ext[3].decrypt("abcd");
var ret2 = msg[0].decryptAndVerifySignature( msg[0].decrypt(priv_key_gnupg_ext[3]);
{ key: priv_key_gnupg_ext[0], keymaterial: priv_key_gnupg_ext[0].subKeys[0]}, msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
msg[0].sessionKeys[0], msg[1].packets[2].verify(pub_key[0], msg[1].packets[1]);
[{obj:pub_key[0], keyId: pub_key[0].getKeyId()}]); result[1] = new unit.result("Testing GnuPG stripped-key extensions",
result[1] = new test_result("Testing GnuPG stripped-key extensions", msg[1].packets[2].verified === true);
priv_key_gnupg_ext[0].privateKeyPacket.s2k.type == 1001 &&
ret.validSignatures[0] == true);
// Exercises the ability of openpgp_keyring.getPublicKeysForKeyId to return subkeys // Exercises the ability of openpgp_keyring.getPublicKeysForKeyId to return subkeys
var test_keyring = new openpgp_keyring(); keyring.init();
test_keyring.init(); keyring.importPacketlist([
test_keyring.importPublicKey([
'-----BEGIN PGP PUBLIC KEY BLOCK-----', '-----BEGIN PGP PUBLIC KEY BLOCK-----',
'Version: GnuPG v1.4.11 (GNU/Linux)', 'Version: GnuPG v1.4.11 (GNU/Linux)',
'', '',
@ -151,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.read_message([ var msg2 = openpgp.readArmoredPackets([
'-----BEGIN PGP MESSAGE-----', '-----BEGIN PGP MESSAGE-----',
'Version: GnuPG v1.4.11 (GNU/Linux)', 'Version: GnuPG v1.4.11 (GNU/Linux)',
'', '',
@ -161,8 +159,8 @@ unit.register("Testing of binary signature checking", function() {
'=WaSx', '=WaSx',
'-----END PGP MESSAGE-----' '-----END PGP MESSAGE-----'
].join("\n")); ].join("\n"));
var pubKey = test_keyring.getPublicKeysForKeyId(msg2[1].signature.issuerKeyId); var pubKey = keyring.getPacketlistForKeyId(msg2[1].signature.issuerKeyId);
result[2] = new test_result("Testing keyring public subkey support", result[2] = new unit.result("Testing keyring public subkey support",
pubKey != null && pubKey != null &&
pubKey.length == 1 && pubKey.length == 1 &&
msg2[1].signature.verify(msg2[0].data, pubKey[0])); msg2[1].signature.verify(msg2[0].data, pubKey[0]));

File diff suppressed because one or more lines are too long