Commit d8894109 authored by Cédric Moreau's avatar Cédric Moreau

Add gen-updates command

parent f98339d6
......@@ -124,6 +124,11 @@ KeySchema.statics.findMembersWhereSignatory = function(signatory, done){
Key.find({ member: true, signatories: new RegExp(signatory.substring(24) + '$') }, done);
};
KeySchema.statics.findMembersWithUpdates = function(done){
var Key = this.model('Key');
Key.find({ member: true, $or: [ {signatories: { $not: { $size: 0 }}}, { subkeys: { $not: { $size: 0 }}}] }, done);
};
KeySchema.statics.addMember = function(fingerprint, done){
var Key = this.model('Key');
Key.update({ fingerprint: fingerprint }, { member: true }, function (err) {
......
......@@ -128,6 +128,23 @@ PublicKeySchema.methods = {
if (hashedCertifs[md5hash]) {
var decoded = base64.decode(hashedCertifs[md5hash]);
var otherList = new openpgp.packet.List();
// Should read a 1 packet list (signature)
otherList.read(decoded);
packets.concat(otherList);
}
});
return packets;
},
getSubkeysFromMD5List: function (md5array){
var packets = new openpgp.packet.List();
var key = keyhelper.fromArmored(this.raw);
var hashedSubkeys = key.getHashedSubkeyPackets();
md5array.forEach(function(md5hash){
if (hashedSubkeys[md5hash]) {
var decoded = base64.decode(hashedSubkeys[md5hash]);
var otherList = new openpgp.packet.List();
// Should read a 2 packets list (subkey + binding signature)
otherList.read(decoded);
packets.concat(otherList);
}
......
......@@ -267,8 +267,8 @@ function KeyService (conn, conf, PublicKeyService) {
async.parallel({
certifications: function(callback){
// Check certifications
kc.certifiers = [];
async.forEach(keyhelper.toPacketlist(kc.certpackets), function(certif, callback2){
kc.certifiers = [];
async.waterfall([
function (next){
checkCertificationOfKey(certif, kc.fingerprint, newKeys, next);
......@@ -330,8 +330,8 @@ function KeyService (conn, conf, PublicKeyService) {
// TODO: check subkeys?
// Check certifications
kc.certifiers = [];
async.forEach(keyhelper.toPacketlist(kc.certpackets), function(certif, callback){
kc.certifiers = [];
async.waterfall([
function (next){
checkCertificationOfKey(certif, kc.fingerprint, newKeys, next);
......@@ -725,6 +725,67 @@ function KeyService (conn, conf, PublicKeyService) {
done(null, block);
}
/**
* Generate a "newcomers" keyblock
*/
this.generateUpdates = function (done) {
var updates = {};
var subupdates = {};
async.waterfall([
function (next){
Key.findMembersWithUpdates(next);
},
function (members, next){
async.forEachSeries(members, function(member, callback){
var fpr = member.fingerprint;
async.waterfall([
function (next){
PublicKey.getTheOne(fpr, next);
},
function (pubkey, next){
var key = pubkey.getKey();
var finalPackets = new openpgp.packet.List();
var certifs = pubkey.getCertificationsFromMD5List(member.certifs);
var subkeys = pubkey.getSubkeysFromMD5List(member.subkeys);
if (subkeys.length > 0) {
subupdates[fpr] = subkeys;
}
async.forEachSeries(certifs, function(certif, callback){
var issuerKeyId = certif.issuerKeyId.toHex().toUpperCase();
async.waterfall([
function (next){
TrustedKey.getTheOne(issuerKeyId, next);
},
function (trusted, next){
// Issuer is a member
finalPackets.push(certif);
next();
},
], function (err) {
// Issuer is not a member
callback();
});
}, function(err){
if (finalPackets.length > 0) {
updates[fpr] = finalPackets;
}
next();
});
},
], callback);
}, next);
},
function (next){
KeyBlock.current(function (err, current) {
next(null, current || null);
});
},
function (current, next){
createNewcomerBlock(current, null, {}, updates, subupdates, next);
},
], done);
}
/**
this.generateNewcomers = function (done) {
* Generate a "newcomers" keyblock
......@@ -922,7 +983,7 @@ function KeyService (conn, conf, PublicKeyService) {
updates[signedFPR] = keptCertifs;
});
// Create the block
createNewcomerBlock(current, wotMembers.concat(realNewcomers), finalJoinData, updates, next);
createNewcomerBlock(current, wotMembers.concat(realNewcomers), finalJoinData, updates, {}, next);
},
], done);
};
......@@ -997,7 +1058,7 @@ function KeyService (conn, conf, PublicKeyService) {
return matched;
}
function createNewcomerBlock (current, members, joinData, updates, done) {
function createNewcomerBlock (current, members, joinData, updates, subupdates, done) {
var block = new KeyBlock();
block.version = 1;
block.currency = current ? current.currency : conf.currency;
......@@ -1005,14 +1066,24 @@ function KeyService (conn, conf, PublicKeyService) {
block.previousHash = current ? current.hash : "";
block.previousIssuer = current ? current.issuer : "";
// Members merkle
members.sort();
var tree = merkle(members, 'sha1').process();
block.membersCount = members.length;
block.membersRoot = tree.root();
block.membersChanges = [];
_(joinData).keys().forEach(function(fpr){
block.membersChanges.push('+' + fpr);
});
if (members) {
members.sort();
var tree = merkle(members, 'sha1').process();
block.membersCount = members.length;
block.membersRoot = tree.root();
block.membersChanges = [];
_(joinData).keys().forEach(function(fpr){
block.membersChanges.push('+' + fpr);
});
} else if (!members && current) {
// No members changes
block.membersCount = current.membersCount;
block.membersRoot = current.membersRoot;
block.membersChanges = [];
} else {
done('Wrong new block: cannot make a root block without members');
return;
}
// Keychanges - newcomers
block.keysChanges = [];
_(joinData).values().forEach(function(join){
......@@ -1029,13 +1100,16 @@ function KeyService (conn, conf, PublicKeyService) {
});
});
// Keychanges - updates: signatures from newcomers
_(updates).keys().forEach(function(fpr){
if (updates[fpr].length > 0) {
var updateKeys = _(updates).keys();
var subkeyKeys = _(subupdates).keys();
var allUpdates = _(updateKeys.concat(subkeyKeys)).uniq();
allUpdates.forEach(function(fpr){
if ((updates[fpr] && updates[fpr].length > 0) || (subupdates[fpr] && subupdates[fpr].length > 0)) {
block.keysChanges.push({
type: 'U',
fingerprint: fpr,
keypackets: '',
certpackets: base64.encode(updates[fpr].write()),
keypackets: subupdates[fpr] ? base64.encode(subupdates[fpr].write()) : '',
certpackets: updates[fpr] ? base64.encode(updates[fpr].write()) : '',
membership: {}
});
}
......
......@@ -226,6 +226,11 @@ program
.description('Tries to generate the next keyblock of the keychain without any changes')
.action(service(DO_NOT_LISTEN_HTTP, ucoin.createWOTServer, generateAndSend("generateEmptyNext")));
program
.command('gen-updates [host] [port] [difficulty]')
.description('Tries to generate an update (#2+) keyblock, containing only update changes')
.action(service(DO_NOT_LISTEN_HTTP, ucoin.createWOTServer, generateAndSend("generateUpdates")));
program
.command('gen-newcomers [host] [port] [difficulty]')
.description('Tries to generate a newcomers (#2+) keyblock, containing only newcomers changes')
......
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