Commit 474e410a authored by Cédric Moreau's avatar Cédric Moreau

Implementing keychange entity

parent cde50084
module.exports = function multipleLinesExtraction(am, wholeAmend, cap) {
var fieldValue = wholeAmend.match(cap.regexp);
am[cap.prop] = [];
if(fieldValue && fieldValue.length == 2){
if(fieldValue && fieldValue.length >= 2){
var lines = fieldValue[1].split(/\n/);
if(lines[lines.length - 1].match(/^$/)){
for (var i = 0; i < lines.length - 1; i++) {
......
......@@ -145,8 +145,8 @@ module.exports = new function() {
return unix2dos(signed(that.getMembershipWithoutSignature(json), json));
};
var KEYBLOCK_PUBK_PREFIX = "#####-----"
var KEYBLOCK_PUBK_SUFFIX = "-----#####"
var KEYBLOCK_PUBK_PREFIX = "#####----";
var KEYBLOCK_PUBK_SUFFIX = "----#####";
this.getKeyblockWithoutSignature = function (json) {
var raw = "";
......@@ -193,6 +193,27 @@ module.exports = new function() {
return unix2dos(signed(that.getKeyblockWithoutSignature(json), json));
};
var KEYCHANGE_PREFIX = "#####----";
var KEYCHANGE_SUFFIX = "----#####";
this.getKeychangeWithoutSignature = function (json) {
var raw = KEYCHANGE_PREFIX + json.type + ":" + json.fingerprint + KEYCHANGE_SUFFIX + "\n";
if (json.keypackets)
raw += "KeyPackets:\n" + json.keypackets;
if (json.certpackets)
raw += "CertificationPackets:\n" + json.certpackets;
if (json.membership.membership) {
raw += "Membership:\n";
raw += json.membership.membership + "\n";
raw += json.membership.signature;
}
return unix2dos(raw);
};
this.getKeychange = function (json) {
return unix2dos(signed(that.getKeychangeWithoutSignature(json), json));
};
function signed (raw, json) {
if (json.signature)
raw += json.signature;
......
module.exports = function simpleLineExtraction(pr, rawEntry, cap, parser) {
var fieldValue = rawEntry.match(cap.regexp);
if(fieldValue && fieldValue.length === 2){
if(fieldValue && fieldValue.length >= 2){
pr[cap.prop] = cap.parser ? cap.parser(fieldValue[1]) : fieldValue[1];
}
return;
......
......@@ -7,6 +7,7 @@ module.exports = {
parseWallet: instanciate.bind(instanciate, require('./wallet')),
parseMembership: instanciate.bind(instanciate, require('./membership')),
parseKeyblock: instanciate.bind(instanciate, require('./keyblock')),
parseKeychange: instanciate.bind(instanciate, require('./keychange')),
};
function instanciate (constructorFunc, onError) {
......
var GenericParser = require('./GenericParser');
var rawer = require('../../../rawer');
var util = require('util');
var sha1 = require('sha1');
var split = require('../../../split');
var unix2dos = require('../../../unix2dos');
var _ = require('underscore');
module.exports = KeychangeParser;
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]*).+:/, parser: extractBase64Lines},
{prop: "certpackets", regexp: /CertificationPackets:\n([\s\S]*)(Membership)?/, parser: extractBase64Lines},
{prop: "membership", regexp: /Membership:\n([\s\S]*)/, parser: extractMembership},
];
var multilineFields = [];
GenericParser.call(this, captures, multilineFields, rawer.getKeychange, onError);
this._clean = function (obj) {
};
this._verify = function(obj){
var err = null;
var code = 150;
var codes = {
'BAD_TYPE': 150,
'BAD_FINGERPRINT': 151
}
if(!err){
// Type
if(!obj.type || !obj.type.match(/^(F|N|U|L|B)$/))
err = {code: codes['BAD_TYPE'], message: "Type must be either F,N,U,L or B"};
}
if(!err){
// Fingerprint
if(!obj.fingerprint || !obj.fingerprint.match(/^[A-Z\d]{40}$/))
err = {code: codes['BAD_FINGERPRINT'], message: "Fingerprint must match an uppercased SHA-1 hash"};
}
return err && err.message;
};
}
function extractBase64Lines(raw) {
var validLines = "";
var lines = raw.split(/\n/);
// console.log('raw = ', raw);
lines.forEach(function(line){
if (line.match(/^[A-Za-z0-9\/+=]{1,64}$/)) {
validLines += line + '\n';
}
});
return validLines;
}
function extractMembership(raw) {
var splits = raw ? raw.split(/\n/) : [""];
var inlineMS = splits[0];
var lines = splits.slice(1, splits.length - 1);
var validLines = "";
lines.forEach(function(line){
if (line.match(/^[A-Za-z0-9\/+=]{1,64}$/)) {
validLines += line + '\n';
}
});
return { membership: inlineMS, signature: validLines };
}
util.inherits(KeychangeParser, GenericParser);
var should = require('should');
var assert = require('assert');
var async = require('async');
var fs = require('fs');
var openpgp = require('openpgp');
var base64 = require('../../app/lib/base64');
var jpgp = require('../../app/lib/jpgp');
var mongoose = require('mongoose');
var parsers = require('../../app/lib/streams/parsers/doc');
var keychangeRaw = "" +
"#####----F:C73882B64B7E72237A2F460CE9CAB76D19A8651E----#####\r\n" +
"KeyPackets:\r\n" +
"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\r\n" +
"SxwkCr+V2HghBDxZqmr0TYy1\r\n" +
"Membership:\r\n" +
"1:C73882B64B7E72237A2F460CE9CAB76D19A8651E:IN:1408115509:LoL Cat (udid2;c;CAT;LOL;2000-04-19;e+43.70-079.42;0;) <cem.moreau@gmail.com>\r\n" +
"iQEcBAABAgAGBQJT7iVTAAoJEOnKt20ZqGUeUm0IAM8KNv4+/iMEmQux/n0NIcfD\r\n" +
"1eo/eo44dn0vxhkN3jbWHrCSJLiN7UvlfOyle5hiK+Ods/eipLZBiSROhTRyt1Y2\r\n" +
"Z+pxn+zGPFq/cmo8CHV+y/hTxYGwHJBE6+TJ+1xpRvMrTm4qLm6n/dZ/qVPPivRE\r\n" +
"xWYBMK1f7NzmqsrbiK27L8gxIZy/6CCBCkmcAnOPcOGQ4fiQcvjkCRqKZg6+MXCi\r\n" +
"W3e3YNwcGYmNDs5/wpgZ0rpP391SNKuADG3dQHcTA91A9Suxlz0gmnsNCV90SjsN\r\n" +
"KagV6MtZ05SDuf3ZvJxQI/6ReL6KeOIsrpolTBeJGMsU1/+9l8zh5fEgDcJqSkw=\r\n" +
"=3Iri\r\n";
describe('Founder packet (Cat)', function(){
var keychange;
before(function(done) {
var parser = parsers.parseKeychange().asyncWrite(keychangeRaw, function (err, obj) {
keychange = obj;
done(err);
});
});
it('should have 4 key packets', function(){
var pubkeyPackets = keychange.keypackets;
var packetList = new openpgp.packet.List();
packetList.read(base64.decode(pubkeyPackets));
var pubkey = new openpgp.key.Key(packetList);
assert.equal(packetList.length, 4);
assert.equal(pubkey.getFingerprint().toUpperCase(), 'C73882B64B7E72237A2F460CE9CAB76D19A8651E');
});
});
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