Commit 9120ef6e authored by Cédric Moreau's avatar Cédric Moreau

Add WoT stability checking before accepting a block with newcomers

parent 0ed0158d
......@@ -197,6 +197,18 @@ function KeyHelper (packetList) {
return certifs;
};
this.getCertificationsFromSignatory = function (newcomer){
var primaryUser = key.getPrimaryUser();
var certifs = new PacketList();
if (primaryUser) {
(primaryUser.user.otherCertifications || []).forEach(function(oCert){
if (newcomer.match(new RegExp(oCert.issuerKeyId.toHex().toUpperCase() + '$')))
certifs.push(oCert);
});
}
return certifs;
};
// Give base64 encoded signing subkey packets (subkey + binding)
this.getBase64subkeys = function (){
var bSubkeys = [];
......
......@@ -55,6 +55,10 @@ function GenericParser (captures, multipleLinesFields, rawerFunc, onError) {
error = 'Document has unkown fields or wrong line ending format';
if (error) {
console.log(error);
// console.log('-----------------');
// console.log('Written:', { str: str });
// console.log('Extract:', { raw: raw });
// console.log('-----------------');
}
}
if (typeof done == 'function')
......
......@@ -120,7 +120,7 @@ function extractKeyChanges(raw) {
if (line.match(/^#####----(F|N|U|L|B):[A-Z0-9]{40}----#####$/)) {
// New key block
if (currentKC)
rawKeychanges.push(currentKC);
rawKeychanges.push(unix2dos(currentKC));
currentKC = line + '\n';
} else {
// Adding to current
......@@ -128,7 +128,7 @@ function extractKeyChanges(raw) {
}
});
if (currentKC)
rawKeychanges.push(currentKC);
rawKeychanges.push(unix2dos(currentKC));
rawKeychanges.forEach(function(kc){
var parsers = require('./.');
var obj = parsers.parseKeychange().syncWrite(kc);
......
......@@ -13,8 +13,8 @@ function KeychangeParser (onError) {
var captures = [
{prop: "type", regexp: /#####----([FNULB]):[A-Z0-9]{40}----#####/},
{prop: "fingerprint", regexp: /#####----[FNULB]:([A-Z0-9]{40})----#####/},
{prop: "keypackets", regexp: /KeyPackets:\n([\s\S]*?)[a-zA-Z]+:/, parser: extractBase64Lines},
{prop: "certpackets", regexp: /CertificationPackets:\n([\s\S]*?)[a-zA-Z]+:/, parser: extractBase64Lines},
{prop: "keypackets", regexp: /KeyPackets:\n([\s\S]*)/, parser: extractBase64Lines},
{prop: "certpackets", regexp: /CertificationPackets:\n([\s\S]*)/, parser: extractBase64Lines},
{prop: "membership", regexp: /Membership:\n([\s\S]*)/, parser: extractMembership},
];
var multilineFields = [];
......@@ -50,9 +50,12 @@ function extractBase64Lines(raw) {
var validLines = "";
var splits = raw.split(/\n/);
var lines = splits.slice(0, splits.length - 1);
var lineOfBlock = true;
lines.forEach(function(line){
if (line.match(/^[A-Za-z0-9\/+=]{1,64}$/)) {
if (lineOfBlock && line.match(/^[A-Za-z0-9\/+=]{1,64}$/)) {
validLines += line + '\n';
} else {
lineOfBlock = false;
}
});
return validLines;
......
......@@ -13,6 +13,7 @@ var KeySchema = new Schema({
distanced: [String], // Array of distanced keys fingerprints
certifs: [String], // Array of md5 hashes of packets to integrate
subkeys: [String], // Array of md5 hashes of packets to integrate
signatories: [String], // Array of md5 hashes of packets to integrate
created: { type: Date, default: Date.now },
updated: { type: Date, default: Date.now }
});
......@@ -118,6 +119,11 @@ KeySchema.statics.getMembers = function(done){
Key.find({ member: true }, done);
};
KeySchema.statics.findWhereSignatory = function(signatory, done){
var Key = this.model('Key');
Key.find({ signatories: new RegExp(signatory.substring(24) + '$') }, done);
};
KeySchema.statics.addMember = function(fingerprint, done){
var Key = this.model('Key');
Key.update({ fingerprint: fingerprint }, { member: true }, function (err) {
......
......@@ -43,14 +43,10 @@ LinkSchema.statics.unobsoletesAllLinks = function (done) {
/**
* Mark as obsolete the links with an age equal to or below a given date
**/
LinkSchema.statics.isStillOver3Steps = function (keyToKick, newLinks, done) {
LinkSchema.statics.isStillOver3Steps = function (fpr, ofMembers, newLinks, done) {
var Link = this.model('Link');
var fpr = keyToKick.fingerprint;
var newCertifiers = newLinks[fpr];
var remainingKeys = [];
keyToKick.distanced.forEach(function(m){
remainingKeys.push(m);
});
var newCertifiers = newLinks[fpr] || [];
var remainingKeys = ofMembers.slice();
// Without self
remainingKeys = _(remainingKeys).difference([fpr]);
var dist1Links = [];
......@@ -66,7 +62,7 @@ LinkSchema.statics.isStillOver3Steps = function (keyToKick, newLinks, done) {
Link.find({ target: fpr, obsolete: false }, function (err, links) {
dist1Links = [];
links.forEach(function(lnk){
dist1Links.push(lnk.fingerprint);
dist1Links.push(lnk.source);
});
// Add new certifiers as distance 1 links
dist1Links = _(dist1Links.concat(newCertifiers)).uniq();
......@@ -82,6 +78,12 @@ LinkSchema.statics.isStillOver3Steps = function (keyToKick, newLinks, done) {
async.forEachSeries(remainingKeys, function(member, callback){
// Exists distance 1 link?
async.detect(dist1Links, function (dist1member, callbackDist1) {
// Look in newLinks
var signatories = newLinks[dist1member];
if (~signatories.indexOf(member)) {
callbackDist1(true);
return;
}
// dist1member signed 'fpr', so here we look for (member => dist1member => fpr sigchain)
Link.find({ source: member, target: dist1member, obsolete: false }, function (err, links) {
if (links && links.length > 0) {
......@@ -112,19 +114,34 @@ LinkSchema.statics.isStillOver3Steps = function (keyToKick, newLinks, done) {
async.waterfall([
function (next){
// Step 1. Detect distance 1 members from current member (potential dist 2 from 'fpr')
// Look in database
Link.find({ source: member, obsolete: false }, function (err, links) {
dist2Links = [];
links.forEach(function(lnk){
dist2Links.push(lnk.fingerprint);
dist2Links.push(lnk.source);
});
next(err);
});
// Look in newLinks
_(newLinks).keys().forEach(function(signed){
newLinks[signed].forEach(function(signatories){
if (~signatories.indexOf(member)) {
dist2links.push(signed);
}
});
});
},
function (next){
// Step 2. Detect links between distance 2 & distance 1 members
async.detect(dist2Links, function (dist2member, callbackDist2) {
// Exists distance 1 link?
async.detect(dist1Links, function (dist1member, callbackDist1) {
// Look in newLinks
var signatories = newLinks[dist1member];
if (~signatories.indexOf(dist2member)) {
callbackDist1(true);
return;
}
// dist1member signed 'fpr', so here we look for (member => dist1member => fpr sigchain)
Link.find({ source: dist2member, target: dist1member, obsolete: false }, function (err, links) {
if (links && links.length > 0) {
......
This diff is collapsed.
......@@ -109,10 +109,17 @@ function PublicKeyService (conn, conf, KeyService) {
var recordedSubKeys = _((keyT && keyT.getHashedSubkeyPackets()) || {}).keys();
var availableSubKeys = _(keyN.getHashedSubkeyPackets()).keys();
// Compute new certifications
var hashedCertifs = keyN.getHashedCertifPackets();
var recordedCertifs = _((keyT && keyT.getHashedCertifPackets()) || {}).keys();
var availableCertifs = _(keyN.getHashedCertifPackets()).keys();
var availableCertifs = _(hashedCertifs).keys();
key.subkeys = _(availableSubKeys).difference(recordedSubKeys);
key.certifs = _(availableCertifs).difference(recordedCertifs);
key.signatories = [];
key.certifs.forEach(function(hash){
var certif = keyhelper.toPacketlist(hashedCertifs[hash]);
var issuer = certif[0].issuerKeyId.toHex().toUpperCase();
key.signatories.push(issuer);
});
key.eligible = keyN.hasValidUdid2();
key.save(function (err) {
next(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