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