From 753b1fc6377c6e9a709d2ce59f1eb9121697d342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Obernd=C3=B6rfer?= Date: Mon, 10 Feb 2014 18:57:17 +0100 Subject: [PATCH] Method getKeysForKeyId renamed and optimized, returns only single key. Deep optional parameter to search also in subkeys. Add method getKeyForLongId with same properties. Optimize access to keyid and fingerprint by using a buffer. --- src/keyring/keyring.js | 43 ++++++++++++++++++++++++++++++++++++---- src/packet/public_key.js | 36 ++++++++++++++++++++++++--------- 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/src/keyring/keyring.js b/src/keyring/keyring.js index 2c8388a2..4c414300 100644 --- a/src/keyring/keyring.js +++ b/src/keyring/keyring.js @@ -145,12 +145,47 @@ Keyring.prototype.getPrivateKeyForAddress = function (email) { }; /** - * Searches the keyring for public keys having the specified key id + * Searches the keyring for a key having the specified key id * @param {String} keyId provided as string of hex number (lowercase) - * @return {Array} public keys found + * @param {Boolean} deep if true search also in subkeys + * @return {module:key~Key|null} key found or null */ -Keyring.prototype.getKeysForKeyId = function (keyId) { - return checkForIdentityAndKeyTypeMatch(this.keys, idCheck, keyId, enums.packet.publicKey); +Keyring.prototype.getKeyForId = function (keyId, deep) { + for (var i = 0; i < this.keys.length; i++) { + if (this.keys[i].primaryKey.getKeyId().toHex() === keyId) { + return this.keys[i]; + } + if (deep) { + for (var j = 0; j < this.keys[i].subKeys.length; j++) { + if (this.keys[i].subKeys[j].getKeyId().toHex() === keyId) { + return this.keys[i]; + } + } + } + } + return null; +}; + +/** + * Searches the keyring for a key having the specified long key id (fingerprint) + * @param {String} longKeyId fingerprint in lowercase hex + * @param {Boolean} deep if true search also in subkeys + * @return {module:key~Key|null} key found or null + */ +Keyring.prototype.getKeyForLongId = function(longKeyId, deep) { + for (var i = 0; i < this.keys.length; i++) { + if (this.keys[i].primaryKey.getFingerprint() === longKeyId) { + return this.keys[i]; + } + if (deep) { + for (var j = 0; j < this.keys[i].subKeys.length; j++) { + if (this.keys[i].subKeys[j].getFingerprint() === longKeyId) { + return this.keys[i]; + } + } + } + } + return null; }; /** diff --git a/src/packet/public_key.js b/src/packet/public_key.js index 35965c47..770ad210 100644 --- a/src/packet/public_key.js +++ b/src/packet/public_key.js @@ -55,6 +55,16 @@ function PublicKey() { this.algorithm = 'rsa_sign'; // time in days (V3 only) this.expirationTimeV3 = 0; + /** + * Fingerprint in lowercase hex + * @type {String} + */ + this.fingerprint = null; + /** + * Keyid + * @type {module:type/keyid} + */ + this.keyid = null; } /** @@ -158,31 +168,39 @@ PublicKey.prototype.writeOld = function () { * @return {String} A 8 byte key id */ PublicKey.prototype.getKeyId = function () { - var keyid = new type_keyid(); - if (this.version == 4) { - keyid.read(this.getFingerprint().substr(12, 8)); - } else if (this.version == 3) { - keyid.read(this.mpi[0].write().substr(-8)); + if (this.keyid) { + return this.keyid; } - return keyid; + this.keyid = new type_keyid(); + if (this.version == 4) { + this.keyid.read(util.hex2bin(this.getFingerprint()).substr(12, 8)); + } else if (this.version == 3) { + this.keyid.read(this.mpi[0].write().substr(-8)); + } + return this.keyid; }; /** * Calculates the fingerprint of the key - * @return {String} A string containing the fingerprint + * @return {String} A string containing the fingerprint in lowercase hex */ PublicKey.prototype.getFingerprint = function () { + if (this.fingerprint) { + return this.fingerprint; + } var toHash = ''; if (this.version == 4) { toHash = this.writeOld(); - return crypto.hash.sha1(toHash); + this.fingerprint = crypto.hash.sha1(toHash); } else if (this.version == 3) { var mpicount = crypto.getPublicMpiCount(this.algorithm); for (var i = 0; i < mpicount; i++) { toHash += this.mpi[i].toBytes(); } - return crypto.hash.md5(toHash); + this.fingerprint = crypto.hash.md5(toHash); } + this.fingerprint = util.hexstrdump(this.fingerprint); + return this.fingerprint; }; /**