Commit 7a7e2779 authored by Cédric Moreau's avatar Cédric Moreau

Now correctly concats new certifications & subkeys

parent 964b8ebb
......@@ -38,6 +38,10 @@ module.exports = {
return packets;
},
toEncoded: function (packetList){
return base64.encode(packetList.write());
},
hasOnlySubkeyMaterial: function (encodedPackets){
var packets = new PacketList();
packets.read(base64.decode(encodedPackets));
......@@ -102,6 +106,10 @@ function KeyHelper (packetList) {
return primaryUser && primaryUser.user && primaryUser.user.userId && primaryUser.user.userId.userid;
};
this.getEncodedPacketList = function (){
return base64.encode(key.toPacketlist().write());
};
this.getFounderPackets = function (){
var packets = new openpgp.packet.List();
// Primary key
......
var mongoose = require('mongoose');
var async = require('async');
var sha1 = require('sha1');
var _ = require('underscore');
var fs = require('fs');
var Schema = mongoose.Schema;
var base64 = require('../lib/base64');
var openpgp = require('openpgp');
var logger = require('../lib/logger')('dao keyblock');
var mongoose = require('mongoose');
var async = require('async');
var sha1 = require('sha1');
var _ = require('underscore');
var fs = require('fs');
var Schema = mongoose.Schema;
var base64 = require('../lib/base64');
var openpgp = require('openpgp');
var keyhelper = require('../lib/keyhelper');
var logger = require('../lib/logger')('dao keyblock');
var KeyBlockSchema = new Schema({
version: String,
......@@ -81,6 +82,27 @@ KeyBlockSchema.methods = {
return pubkeys;
},
getKeyUpdates: function() {
var updates = {};
this.keysChanges.forEach(function(kc){
updates[kc.fingerprint] = { certifs: '', subkeys: '' };
var list = new openpgp.packet.List();
if (kc.type == 'U' || kc.type == 'B') {
// Subkeys
if (kc.keypackets) {
list.concat(keyhelper.toPacketlist(kc.keypackets));
updates[kc.fingerprint].subkeys = keyhelper.toEncoded(list);
}
// Certifs
if (kc.certpackets) {
list.concat(keyhelper.toPacketlist(kc.certpackets));
updates[kc.fingerprint].certifs = keyhelper.toEncoded(list);
}
}
});
return updates;
},
getPublicKeysPackets: function() {
var pubkeys = [];
this.publicKeys.forEach(function(obj){
......
......@@ -621,8 +621,38 @@ function KeyService (conn, conf, PublicKeyService) {
}, next);
},
function (next){
// Save key updates
next();
// Save key updates (from UPDATE & BACK)
var updates = block.getKeyUpdates();
async.forEach(_(updates).keys(), function(fpr, callback){
async.waterfall([
function (next){
TrustedKey.getTheOne(fpr, next);
},
function (trusted, next){
var oldList = keyhelper.toPacketlist(trusted.packets);
var newList = new openpgp.packet.List();
if (updates[fpr].certifs) {
// Concat signature packets behind userid + self-signature
for (var i = 0; i < 3; i++)
newList.push(oldList[i]);
newList.concat(keyhelper.toPacketlist(updates[fpr].certifs));
// Concat remaining packets
for (var i = 3; i < oldList.length; i++)
newList.push(oldList[i]);
} else {
// Write the whole existing key
newList.concat(oldList);
}
if (updates[fpr].subkeys)
newList.concat(keyhelper.toPacketlist(updates[fpr].subkeys));
var key = keyhelper.fromPackets(newList);
trusted.packets = key.getEncodedPacketList();
trusted.save(function (err) {
next(err);
});
},
], callback);
}, next);
},
function (next){
// Save links
......@@ -650,6 +680,10 @@ function KeyService (conn, conf, PublicKeyService) {
// Compute obsolete links
computeObsoleteLinks(block, next);
},
function (next){
// Update available key material for members with keychanges in this block
updateAvailableKeyMaterial(block, next);
},
], function (err) {
done(err, block);
});
......@@ -680,6 +714,24 @@ function KeyService (conn, conf, PublicKeyService) {
], done);
}
function saveKeyUpdates (block, done) {
async.forEach(block.keysChanges, function(kc, callback){
if (kc.type != 'L') {
PublicKeyService.updateAvailableKeyMaterial(kc.fingerprint, callback);
}
else callback();
}, done);
}
function updateAvailableKeyMaterial (block, done) {
async.forEach(block.keysChanges, function(kc, callback){
if (kc.type != 'L') {
PublicKeyService.updateAvailableKeyMaterial(kc.fingerprint, callback);
}
else callback();
}, done);
}
function WOTPubkey (fingerprint, rawPackets) {
this.packets = new openpgp.packet.List();
......
......@@ -30,6 +30,7 @@ function PublicKeyService (conn, conf, KeyService) {
*/
this.submitPubkey = function(obj, callback) {
var pubkey = new PublicKey(obj);
var that = this;
fifo.push(function (cb) {
async.waterfall([
function (next) {
......@@ -58,40 +59,7 @@ function PublicKeyService (conn, conf, KeyService) {
});
},
function (next) {
async.parallel({
pubkey: function(callback){
PublicKey.getTheOne(pubkey.fingerprint, callback);
},
trusted: function(callback){
TrustedKey.getTheOne(pubkey.fingerprint, function (err, trusted) {
if (err)
trusted = null;
callback(null, trusted);
});
},
key: function(callback){
Key.getTheOne(pubkey.fingerprint, callback);
},
}, next);
},
function (res, next){
var pubkey = res.pubkey;
var trusted = res.trusted;
var key = res.key;
var keyN = keyhelper.fromArmored(pubkey.raw);
var keyT = trusted == null ? null : keyhelper.fromEncodedPackets(trusted.packets);
// Compute new subkeys
var recordedSubKeys = _((keyT && keyT.getHashedSubkeyPackets()) || {}).keys();
var availableSubKeys = _(keyN.getHashedSubkeyPackets()).keys();
// Compute new certifications
var recordedCertifs = _((keyT && keyT.getHashedCertifPackets()) || {}).keys();
var availableCertifs = _(keyN.getHashedCertifPackets()).keys();
key.subkeys = _(availableSubKeys).without(availableSubKeys);
key.certifs = _(availableCertifs).without(availableCertifs);
key.eligible = keyN.hasValidUdid2();
key.save(function (err) {
next(err);
});
that.updateAvailableKeyMaterial(pubkey.fingerprint, next);
},
], next);
},
......@@ -111,6 +79,48 @@ function PublicKeyService (conn, conf, KeyService) {
}, callback);
};
// Check subkeys, subkey bindings & certifications that can be recorded in the keychain
this.updateAvailableKeyMaterial = function (fpr, done) {
async.waterfall([
function (next) {
async.parallel({
pubkey: function(callback){
PublicKey.getTheOne(fpr, callback);
},
trusted: function(callback){
TrustedKey.getTheOne(fpr, function (err, trusted) {
if (err)
trusted = null;
callback(null, trusted);
});
},
key: function(callback){
Key.getTheOne(fpr, callback);
},
}, next);
},
function (res, next){
var pubkey = res.pubkey;
var trusted = res.trusted;
var key = res.key;
var keyN = keyhelper.fromArmored(pubkey.raw);
var keyT = trusted == null ? null : keyhelper.fromEncodedPackets(trusted.packets);
// Compute new subkeys
var recordedSubKeys = _((keyT && keyT.getHashedSubkeyPackets()) || {}).keys();
var availableSubKeys = _(keyN.getHashedSubkeyPackets()).keys();
// Compute new certifications
var recordedCertifs = _((keyT && keyT.getHashedCertifPackets()) || {}).keys();
var availableCertifs = _(keyN.getHashedCertifPackets()).keys();
key.subkeys = _(availableSubKeys).difference(recordedSubKeys);
key.certifs = _(availableCertifs).difference(recordedCertifs);
key.eligible = keyN.hasValidUdid2();
key.save(function (err) {
next(err);
});
},
], done);
}
this.getForPeer = function (peer, done) {
PublicKey.getTheOne(peer.fingerprint, function (err, pubkey) {
if (!err) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment