Commit 2bc62bcd authored by Cédric Moreau's avatar Cédric Moreau

Now able to generate root keyblock + accept it

parent f7490c82
......@@ -132,7 +132,8 @@ function JPGP() {
catch(ex){
verified = false;
err = ex.toString();
console.log('Exception during signature verification: ' + err);
console.log('Exception during signature verification: ' + ex);
console.log(ex.stack);
}
callback(err, verified);
};
......
......@@ -44,12 +44,40 @@ function KeyHelper (packetList) {
return key && key.primaryKey && key.primaryKey.getFingerprint().toUpperCase();
};
this.getUserID = function (param, next){
this.hasPrimaryKey = function (){
return key && key.primaryKey;
};
this.getArmored = function (){
return key.armor();
};
this.getUserID = function (){
var primaryUser = key.getPrimaryUser();
return primaryUser && primaryUser.user && primaryUser.user.userId && primaryUser.user.userId.userid;
};
this.hasValidUdid2 = function (param, next){
this.getFounderPackets = function (){
var packets = new openpgp.packet.List();
// Primary key
packets.push(key.primaryKey)
// UserID
var primaryUser = key.getPrimaryUser();
if (primaryUser) {
packets.push(primaryUser.user.userId);
packets.push(primaryUser.selfCertificate);
}
// Subkeys
(key.subKeys || []).forEach(function(subkeyWrapper){
if (subkeyWrapper.isValidSigningKey(key.primaryKey) || subkeyWrapper.isValidEncryptionKey(key.primaryKey)) {
packets.push(subkeyWrapper.subKey);
packets.push(subkeyWrapper.bindingSignature);
}
});
return packets;
};
this.hasValidUdid2 = function (){
var userid = that.getUserID();
return userid != null && userid.match(UDID2_FORMAT);
};
......
......@@ -184,8 +184,12 @@ module.exports = new function() {
var raw = KEYCHANGE_PREFIX + json.type + ":" + json.fingerprint + KEYCHANGE_SUFFIX + "\n";
if (json.keypackets)
raw += "KeyPackets:\n" + json.keypackets;
if (!raw.match(/\n$/))
raw += '\n';
if (json.certpackets)
raw += "CertificationPackets:\n" + json.certpackets;
if (!raw.match(/\n$/))
raw += '\n';
if (json.membership.membership) {
raw += "Membership:\n";
raw += json.membership.membership + "\n";
......
......@@ -53,6 +53,9 @@ function GenericParser (captures, multipleLinesFields, rawerFunc, onError) {
var raw = that.rawerFunc(obj);
if (sha1(str) != sha1(raw))
error = 'Document has unkown fields or wrong line ending format';
if (error) {
console.log(error);
}
}
if (typeof done == 'function')
done(error, obj);
......
......@@ -13,7 +13,7 @@ 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: "keypackets", regexp: /KeyPackets:\n([\s\S]*)(Membership|Certification)/, parser: extractBase64Lines},
{prop: "certpackets", regexp: /CertificationPackets:\n([\s\S]*)(Membership)?/, parser: extractBase64Lines},
{prop: "membership", regexp: /Membership:\n([\s\S]*)/, parser: extractMembership},
];
......@@ -48,7 +48,8 @@ function KeychangeParser (onError) {
function extractBase64Lines(raw) {
var validLines = "";
var lines = raw.split(/\n/);
var splits = raw.split(/\n/);
var lines = splits.slice(0, splits.length - 1);
lines.forEach(function(line){
if (line.match(/^[A-Za-z0-9\/+=]{1,64}$/)) {
validLines += line + '\n';
......
......@@ -147,63 +147,6 @@ KeyBlockSchema.methods = {
return certifications;
},
getBasicPublicKeys: function() {
var pubkeys = [];
this.publicKeys.forEach(function(obj){
var packets = new openpgp.packet.List();
var packetsTemp = new openpgp.packet.List();
var packetsFinal = new openpgp.packet.List();
var base64decoded = base64.decode(obj.packets);
packets.read(base64decoded);
packets = packets.filterByTag(
openpgp.enums.packet.publicKey,
openpgp.enums.packet.publicSubkey,
openpgp.enums.packet.userid,
openpgp.enums.packet.signature);
// 1st pass (to keep pubk, userid and certifications)
var fingerprint = "";
packets.forEach(function(p){
if (p.tag == openpgp.enums.packet.signature) {
var signaturesToKeep = [
openpgp.enums.signature.cert_generic,
openpgp.enums.signature.cert_persona,
openpgp.enums.signature.cert_casual,
openpgp.enums.signature.cert_positive,
openpgp.enums.signature.subkey_binding
];
if (~signaturesToKeep.indexOf(p.signatureType))
packetsTemp.push(p);
}
else if (p.tag == openpgp.enums.packet.publicKey) {
fingerprint = p.getFingerprint().toUpperCase();
packetsTemp.push(p);
}
else packetsTemp.push(p);
});
// 2nd pass (to slice tier-signatures)
packets = packets.filterByTag(
openpgp.enums.packet.publicKey,
openpgp.enums.packet.userid,
openpgp.enums.packet.signature);
packetsTemp.forEach(function(p){
if (p.tag == openpgp.enums.packet.signature) {
var signaturesToKeep = [
openpgp.enums.signature.cert_generic,
openpgp.enums.signature.cert_persona,
openpgp.enums.signature.cert_casual,
openpgp.enums.signature.cert_positive,
openpgp.enums.signature.subkey_binding
];
if (fingerprint.match(new RegExp(p.issuerKeyId.toHex().toUpperCase() + '$')))
packetsFinal.push(p);
}
else packetsFinal.push(p);
});
pubkeys.push(new openpgp.key.Key(packetsFinal));
});
return pubkeys;
},
getMemberships: function() {
var notFoundMembership = 0;
var mss = {};
......
......@@ -4,6 +4,7 @@ var sha1 = require('sha1');
var jpgp = require('../lib/jpgp');
var _ = require('underscore');
var rawer = require('../lib/rawer');
var dos2unix = require('../lib/dos2unix');
var Schema = mongoose.Schema;
var MembershipSchema = new Schema({
......@@ -58,6 +59,21 @@ MembershipSchema.methods = {
});
},
inlineValue: function() {
return [this.version, this.issuer, this.membership, this.date.timestamp(), this.userid].join(':');
},
inlineSignature: function() {
var splits = dos2unix(this.signature).split('\n');
var signature = "";
var keep = false;
splits.forEach(function(line){
if (keep && !line.match('-----END PGP') && line != '') signature += line + '\n';
if (line == "") keep = true;
});
return signature;
},
json: function() {
var obj = this;
var json = {};
......@@ -87,6 +103,22 @@ MembershipSchema.methods = {
}
}
MembershipSchema.statics.fromInline = function (inlineMS, inlineSig) {
var Membership = this.model('Membership');
var splitted = inlineMS.split(':');
var signature = '-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v1\n\n';
signature += inlineSig;
signature += '-----END PGP SIGNATURE-----\n';
return new Membership({
version: splitted[0],
issuer: splitted[1],
membership: splitted[2],
date: splitted[3] ? new Date(parseInt(splitted[3])*1000) : 0,
userid: splitted[4],
signature: signature
});
}
MembershipSchema.statics.getEligibleForAmendment = function (amNumber, done) {
this.find({ eligible: true, amNumber: amNumber }, done);
......
This diff is collapsed.
......@@ -9,30 +9,6 @@ var mongoose = require('mongoose');
var parsers = require('../../app/lib/streams/parsers/doc');
var Keyblock = mongoose.model('Keyblock', require('../../app/models/keyblock'));
var catPubkeyPackets = "" +
"xsBNBFHHC/EBCADWTLSN7EGP+n30snndS3ZNcB02foL+0opcS6LK2coPDJLg\n" +
"2nookeJRHZxF3THmZQrKwZOjiuDBinOc5DWlzIS/gD/RaXwntgPFlGKBlBU+\n" +
"g255fr28ziSb5Y1lW4N//nUFdPZzoMmPgRj0b17T0UPCoMR8ZZ/Smk5LINbQ\n" +
"wt+A+LEoxEdEVcq+Tyc0OlEabqO6RFqiKDRiPhGPiCwVQA3yPjb6iCp5gTch\n" +
"ObCxCnDbxA0Mfj9FmHrGbepNHGXxStO4xT0woCb7y02S1E8K08kOc5Bq9e1Y\n" +
"j5I/mdaw4Hn/Wp28lZl1mnO1u1z9ZU/rcglhEyaEOTwasheb44QcdGSfABEB\n" +
"AAHNTUxvTCBDYXQgKHVkaWQyO2M7Q0FUO0xPTDsyMDAwLTA0LTE5O2UrNDMu\n" +
"NzAtMDc5LjQyOzA7KSA8Y2VtLm1vcmVhdUBnbWFpbC5jb20+wsB9BBMBCAAn\n" +
"BQJRxwvxAhsDBQkLR5jvBQsJCAcDBRUKCQgLBRYCAwEAAh4BAheAAAoJEOnK\n" +
"t20ZqGUeZYcH/0ItH4b/O0y7V1Jzc1DZAdn4iDiI7/SF3fN4f6cJCu/SOVb+\n" +
"ERFIb6JK+HNHdVAcMHKaPW625R0FahHUkcXWkkGmQ6+sLIsVZwVN1oeZtlD1\n" +
"2cq9A4UJyfJUXkinMKkI8xpdV8J7s5wFRavOS/qaF5beah0Z+IGwQK0nuXxW\n" +
"pT6UZWbpUfXPQB2Mz2/rpjSWKwO3X4FwwOfDiuZExyH2JPDYshdPcj/x+gnz\n" +
"YW9XfWCJw3rOK42vtM+aLtUpJO0Jh6X/sj/iqyS4rPB4DVCmEgSXPx1P+kqn\n" +
"sz3aNTOIujXS8Faz+TC+eNhn+z3SoTl5gBlNNM171fWFr0BR3nIfIu7CwFwE\n" +
"EAEIAAYFAlOm/AEACgkQJFehWHyg7Zw7KggAnOaLv+/B/szpz+qE61qIVMOB\n" +
"b77R3AcIJW4excA4yWUQIyzhBH/srvp/9OG5aMHuxj5SpNITPMiPgUcH6IEc\n" +
"Dao+5IZSFzV9mfeWvRkHPzjFvVPakLheKK8yFjUzyZPYORs6OO67eSCCKfIp\n" +
"CuCgIFbL9GnBMVUhIxRN12+DkJu9jxDyaEwa0mShRibMWfU/lIBxrWVJIXMN\n" +
"zIQF/IMr19BBT83mfH6h4e4Tg3yat64zYxAlF81xG8k8oaS8/P4DPAISq6Ua\n" +
"hMUN3UJwGzk7HdO7wo0F3e5onOinit7RTpg/tAZX+r3VIj8TzZnl4QpCS15A\n" +
"9r9tAcdC0An1ji4sVQ==\n";
var rawKeyblock = "" +
"Version: 1\r\n" +
"Type: KeyBlock\r\n" +
......@@ -150,34 +126,3 @@ describe('Reading a root keyblock', function(){
});
});
});
describe('Extracting pubkeys of a keyblock', function(){
var block = new Keyblock({ publicKeys: [
{
"number": 0,
"fingerprint": "C73882B64B7E72237A2F460CE9CAB76D19A8651E",
"packets": catPubkeyPackets
}
]});
it('pubkey should give a 1 key array', function(){
var pubkeyPackets = block.getPublicKeysPackets();
assert.equal(pubkeyPackets.length, 1);
assert.equal(pubkeyPackets[0].getFingerprint().toUpperCase(), 'C73882B64B7E72237A2F460CE9CAB76D19A8651E');
});
it('basic pubkey should give a 1 key array', function(){
var keys = block.getBasicPublicKeys();
assert.equal(keys.length, 1);
assert.equal(keys[0].getKeyIds().length, 1);
assert.equal(keys[0].getKeyIds()[0].toHex().toUpperCase(), 'E9CAB76D19A8651E');
assert.equal(keys[0].getUserIds().length, 1);
assert.equal(keys[0].getUserIds()[0], 'LoL Cat (udid2;c;CAT;LOL;2000-04-19;e+43.70-079.42;0;) <cem.moreau@gmail.com>');
assert.equal(keys[0].isPublic(), true);
assert.equal(keys[0].isPrivate(), false);
assert.notEqual(keys[0].getPrimaryUser(), null);
assert.notEqual(keys[0].getPrimaryUser().user, null);
assert.equal(keys[0].getPrimaryUser().user.userId.userid, keys[0].getUserIds()[0]);
});
});
......@@ -6,6 +6,7 @@ var openpgp = require('openpgp');
var base64 = require('../../app/lib/base64');
var jpgp = require('../../app/lib/jpgp');
var mongoose = require('mongoose');
var rawer = require('../../app/lib/rawer');
var parsers = require('../../app/lib/streams/parsers/doc');
var keychangeRaw = "" +
......@@ -100,4 +101,8 @@ describe('Founder packet (Cat)', function(){
it('should have empty certification packets', function(){
assert.equal(keychange.certpackets, '');
});
it('should match original raw', function(){
assert.equal(keychangeRaw, rawer.getKeychange(keychange));
});
});
......@@ -6,6 +6,56 @@ var openpgp = require('openpgp');
var base64 = require('../../app/lib/base64');
var jpgp = require('../../app/lib/jpgp');
var catPubkeyPackets = "" +
"xsBNBFHHC/EBCADWTLSN7EGP+n30snndS3ZNcB02foL+0opcS6LK2coPDJLg\n" +
"2nookeJRHZxF3THmZQrKwZOjiuDBinOc5DWlzIS/gD/RaXwntgPFlGKBlBU+\n" +
"g255fr28ziSb5Y1lW4N//nUFdPZzoMmPgRj0b17T0UPCoMR8ZZ/Smk5LINbQ\n" +
"wt+A+LEoxEdEVcq+Tyc0OlEabqO6RFqiKDRiPhGPiCwVQA3yPjb6iCp5gTch\n" +
"ObCxCnDbxA0Mfj9FmHrGbepNHGXxStO4xT0woCb7y02S1E8K08kOc5Bq9e1Y\n" +
"j5I/mdaw4Hn/Wp28lZl1mnO1u1z9ZU/rcglhEyaEOTwasheb44QcdGSfABEB\n" +
"AAHNTUxvTCBDYXQgKHVkaWQyO2M7Q0FUO0xPTDsyMDAwLTA0LTE5O2UrNDMu\n" +
"NzAtMDc5LjQyOzA7KSA8Y2VtLm1vcmVhdUBnbWFpbC5jb20+wsB9BBMBCAAn\n" +
"BQJRxwvxAhsDBQkLR5jvBQsJCAcDBRUKCQgLBRYCAwEAAh4BAheAAAoJEOnK\n" +
"t20ZqGUeZYcH/0ItH4b/O0y7V1Jzc1DZAdn4iDiI7/SF3fN4f6cJCu/SOVb+\n" +
"ERFIb6JK+HNHdVAcMHKaPW625R0FahHUkcXWkkGmQ6+sLIsVZwVN1oeZtlD1\n" +
"2cq9A4UJyfJUXkinMKkI8xpdV8J7s5wFRavOS/qaF5beah0Z+IGwQK0nuXxW\n" +
"pT6UZWbpUfXPQB2Mz2/rpjSWKwO3X4FwwOfDiuZExyH2JPDYshdPcj/x+gnz\n" +
"YW9XfWCJw3rOK42vtM+aLtUpJO0Jh6X/sj/iqyS4rPB4DVCmEgSXPx1P+kqn\n" +
"sz3aNTOIujXS8Faz+TC+eNhn+z3SoTl5gBlNNM171fWFr0BR3nIfIu7CwFwE\n" +
"EAEIAAYFAlOm/AEACgkQJFehWHyg7Zw7KggAnOaLv+/B/szpz+qE61qIVMOB\n" +
"b77R3AcIJW4excA4yWUQIyzhBH/srvp/9OG5aMHuxj5SpNITPMiPgUcH6IEc\n" +
"Dao+5IZSFzV9mfeWvRkHPzjFvVPakLheKK8yFjUzyZPYORs6OO67eSCCKfIp\n" +
"CuCgIFbL9GnBMVUhIxRN12+DkJu9jxDyaEwa0mShRibMWfU/lIBxrWVJIXMN\n" +
"zIQF/IMr19BBT83mfH6h4e4Tg3yat64zYxAlF81xG8k8oaS8/P4DPAISq6Ua\n" +
"hMUN3UJwGzk7HdO7wo0F3e5onOinit7RTpg/tAZX+r3VIj8TzZnl4QpCS15A\n" +
"9r9tAcdC0An1ji4sVQ==\n";
describe('Reading key packets:', function(){
var packets = new openpgp.packet.List();
packets.read(base64.decode(catPubkeyPackets));
var key = new openpgp.key.Key(packets);
it('fingerprint should be cat\'s one', function(){
assert.equal(key.primaryKey.getFingerprint().toUpperCase(), 'C73882B64B7E72237A2F460CE9CAB76D19A8651E');
});
it('basic pubkey should give a 1 key array', function(){
var keys = [key];
assert.equal(keys.length, 1);
assert.equal(keys[0].getKeyIds().length, 1);
assert.equal(keys[0].getKeyIds()[0].toHex().toUpperCase(), 'E9CAB76D19A8651E');
assert.equal(keys[0].getUserIds().length, 1);
assert.equal(keys[0].getUserIds()[0], 'LoL Cat (udid2;c;CAT;LOL;2000-04-19;e+43.70-079.42;0;) <cem.moreau@gmail.com>');
assert.equal(keys[0].isPublic(), true);
assert.equal(keys[0].isPrivate(), false);
assert.notEqual(keys[0].getPrimaryUser(), null);
assert.notEqual(keys[0].getPrimaryUser().user, null);
assert.equal(keys[0].getPrimaryUser().user.userId.userid, keys[0].getUserIds()[0]);
});
});
var asciiCatPubkey = fs.readFileSync(__dirname + "/../data/lolcat.pub", 'utf8');
describe('Extracting', function(){
......
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