From 99a7b8f69cb719309e440089244a130f592bc403 Mon Sep 17 00:00:00 2001 From: cgeek <cem.moreau@gmail.com> Date: Tue, 5 Aug 2014 00:00:32 +0200 Subject: [PATCH] PublicKey: now parses pubkey and remember eligible packets --- app/lib/keyhelper.js | 78 +++++++++++++++++++++++++++++++++++++++++ app/lib/md5.js | 7 ++++ app/models/publickey.js | 25 +++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 app/lib/keyhelper.js create mode 100644 app/lib/md5.js diff --git a/app/lib/keyhelper.js b/app/lib/keyhelper.js new file mode 100644 index 000000000..4920ecf8b --- /dev/null +++ b/app/lib/keyhelper.js @@ -0,0 +1,78 @@ +var openpgp = require('openpgp'); +var base64 = require('./base64'); +var PacketList = openpgp.packet.List; + +module.exports = { + + fromPackets: function (packetList){ + return new KeyHelper(packetList); + }, + + fromArmored: function (armored){ + var readKeys = openpgp.key.readArmored(asciiArmored).keys; + var packets = new PacketList(); + if(readKeys.length == 1){ + packets = readKeys[0].toPacketList(); + } + return new KeyHelper(packets); + } +}; + +var UDID2_FORMAT = /udid2;c;/; +// var UDID2_FORMAT = /\(udid2;c;([A-Z-]*);([A-Z-]*);(\d{4}-\d{2}-\d{2});(e\+\d{2}\.\d{2}-\d{3}\.\d{2});(\d+)(;?)\)/; + +function KeyHelper (packetList) { + + var that = this; + var key = new openpgp.key.Key(packetList); + + this.getUserID = function (param, next){ + var primaryUser = key.getPrimaryUser(); + return primaryUser && primaryUser.user && primaryUser.user.userId && primaryUser.user.userId.userid; + }; + + this.hasValidUdid2 = function (param, next){ + var userid = that.getUserID(); + return userid != null && userid.match(UDID2_FORMAT); + }; + + this.getBase64publicKey = function (){ + return key.getKeyPacket() && base64.encode(key.getKeyPacket().write()); + }; + + this.getBase64primaryUser = function (){ + var primaryUser = key.getPrimaryUser(); + var packets = new PacketList(); + if (primaryUser) { + packets.push(primaryUser.user.userId); + packets.push(primaryUser.selfCertificate); + } + return primaryUser && base64.encode(packets.write()); + }; + + this.getBase64primaryUserOtherCertifications = function (){ + var primaryUser = key.getPrimaryUser(); + var certifs = []; + if (primaryUser) { + (primaryUser.user.otherCertifications || []).forEach(function(oCert){ + certifs.push(base64.encode(oCert.write())); + // oCert.verify(key, { userid: primaryUser.user.userId, key: key }))) { + }); + } + return certifs; + }; + + // Give base64 encoded signing subkey packets (subkey + binding) + this.getBase64subkeys = function (){ + var bSubkeys = []; + (key.subKeys || []).forEach(function(subkeyWrapper){ + if (subkeyWrapper.isValidSigningKey(key) || subkeyWrapper.isValidEncryptionKey(key)) { + var packets = new PacketList(); + packets.push(subkeyWrapper.subKey); + packets.push(subkeyWrapper.bindingSignature); + bSubkeys.push(base64.encode(packets.write())); + } + }); + return bSubkeys; + }; +} diff --git a/app/lib/md5.js b/app/lib/md5.js new file mode 100644 index 000000000..cba0ee329 --- /dev/null +++ b/app/lib/md5.js @@ -0,0 +1,7 @@ + +module.exports = function (str){ + return require("crypto") + .createHash("md5") + .update(str) + .digest("hex"); +}; diff --git a/app/models/publickey.js b/app/models/publickey.js index bcc747b23..5e23d40a0 100644 --- a/app/models/publickey.js +++ b/app/models/publickey.js @@ -4,6 +4,10 @@ var async = require('async'); var sha1 = require('sha1'); var _ = require('underscore'); var Schema = mongoose.Schema; +var openpgp = require('openpgp'); +var KHelper = require('../lib/keyhelper'); +var base64 = require('../lib/base64'); +var md5 = require('../lib/md5'); var unix2dos = require('../lib/unix2dos'); var parsers = require('../lib/streams/parsers/doc'); var logger = require('../lib/logger')('pubkey'); @@ -13,6 +17,8 @@ var PublicKeySchema = new Schema({ fingerprint: { type: String, unique: true }, subkeys: [String], // Array of keyId hashes: [String], // Array of ASCII armor representation fingerprints + registered: [String], // Array of md5 hashes of the known packets (base64 encoded) + eligible: [String], // Array of md5 hashes of the unknown packets (base64 encoded) name: String, email: String, comment: String, @@ -209,6 +215,25 @@ PublicKeySchema.statics.persist = function (pubkey, done) { var storedKey = jpgp().certificate(foundKeys[0].raw).key; // Merges packets storedKey.update(comingKey); + var kh = KHelper.fromPackets(storedKey.toPacketlist()); + var potentials = []; + if (kh.hasValidUdid2()) { + potentials.push(kh.getBase64publicKey()); + potentials.push(kh.getBase64primaryUser()); + kh.getBase64primaryUserOtherCertifications().forEach(function(base64SubKey){ + potentials.push(base64SubKey); + }); + kh.getBase64subkeys().forEach(function(base64SubKey){ + potentials.push(base64SubKey); + }); + } + potentials.forEach(function(encoded){ + var md5ed = md5(encoded); + if (foundKeys[0].registered.indexOf(md5ed) == -1 && foundKeys[0].eligible.indexOf(md5ed) == -1) { + foundKeys[0].eligible.push(md5ed); + } + }); + // Check for unknown packets var mergedCert = jpgp().certificate(storedKey.armor()); var raw = unix2dos(storedKey.armor()); foundKeys[0].subkeys = mergedCert.subkeys; -- GitLab