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:
parent
766d3e34fe
commit
30d2c38f00
File diff suppressed because one or more lines are too long
|
@ -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;
|
||||||
|
|
249
src/openpgp.js
249
src/openpgp.js
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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";
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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]));
|
||||||
|
|
1209
test/test-bundle.js
1209
test/test-bundle.js
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user