fork-openpgpjs/src/openpgp.keyring.js
Brian Bloniarz 2bb3c30025 openpgp_keyring include subkeys by ID
openpgp_keyring.getPublicKeysForKeyId will now search subkeys
when looking for the ID, and return a key object based on that
subkey.

Updated to add a method, getSubKeyAsKey, to openpgp_msg_publickey.
This returns a full-fledged openpgp_msg_publickey object for a
chosen subkey.
2013-02-13 22:31:27 -08:00

269 lines
9.0 KiB
JavaScript

// GPG4Browsers - An OpenPGP implementation in javascript
// Copyright (C) 2011 Recurity Labs GmbH
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/**
* @class
* @classdesc The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage.
*/
function openpgp_keyring() {
/**
* Initialization routine for the keyring. This method reads the
* keyring from HTML5 local storage and initializes this instance.
* This method is called by openpgp.init().
* @return {null} undefined
*/
function init() {
var sprivatekeys = JSON.parse(window.localStorage.getItem("privatekeys"));
var spublickeys = JSON.parse(window.localStorage.getItem("publickeys"));
if (sprivatekeys == null || sprivatekeys.length == 0) {
sprivatekeys = new Array();
}
if (spublickeys == null || spublickeys.length == 0) {
spublickeys = new Array();
}
this.publicKeys = new Array();
this.privateKeys = new Array();
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;
/**
* 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.
* The privateKeys array and publicKeys array gets Stringified using JSON
* @return {null} undefined
*/
function store() {
var priv = new Array();
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;
/**
* searches all public keys in the keyring matching the address or address part of the user ids
* @param email_address
* @return {array[openpgp_msg_publickey]} the public keys associated with provided email address.
*/
function getPublicKeyForAddress(email_address) {
var results = new Array();
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;
/**
* Searches the keyring for a private key containing the specified email address
* @param {String} email_address email address to search for
* @return {Array[openpgp_msg_privatekey} private keys found
*/
function getPrivateKeyForAddress(email_address) {
var results = new Array();
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;
/**
* Searches the keyring for public keys having the specified key id
* @param keyId provided as string of hex number (lowercase)
* @return {Array[openpgp_msg_privatekey]} public keys found
*/
function getPublicKeysForKeyId(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()
}
}
}
}
}
return result;
}
this.getPublicKeysForKeyId = getPublicKeysForKeyId;
/**
* Searches the keyring for private keys having the specified key id
* @param {String} keyId 8 bytes as string containing the key id to look for
* @return {Array[openpgp_msg_privatekey]} private keys found
*/
function getPrivateKeyForKeyId(keyId) {
var result = new Array();
for (var i=0; i < this.privateKeys.length; i++) {
if (keyId == this.privateKeys[i].obj.getKeyId()) {
result[result.length] = { key: this.privateKeys[i], keymaterial: this.privateKeys[i].obj.privateKeyPacket};
}
if (this.privateKeys[i].obj.subKeys != null) {
var subkeyids = this.privateKeys[i].obj.getSubKeyIds();
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
* @return {null} nothing
*/
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;
}
/**
* Imports a private key from an exported ascii armored message
* @param {String} armored_text PRIVATE KEY BLOCK message to read the private key from
* @return {null} nothing
*/
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
* @param {Integer} index the index of the public key within the publicKeys array
* @return {openpgp_msg_privatekey} the public key object
*/
function exportPublicKey(index) {
return this.publicKey[index];
}
this.exportPublicKey = exportPublicKey;
/**
* 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
* @return {openpgp_msg_privatekey} The public key object which has been removed
*/
function removePublicKey(index) {
var removed = this.publicKeys.splice(index,1);
this.store();
return removed;
}
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;
/**
* 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;
}