Mise à jour de GitLab prévue ce samedi 23 octobre 2021 à partir de 9h00 CET

Commit d9f85edb authored by Cédric Moreau's avatar Cédric Moreau
Browse files

Now using OpenpgpJS as openpgp layer

parent c0d4817a
var exec = require('child_process').exec,
sys = require('sys');
var openpgp = require('./openpgp').openpgp;
var JPGP_JAR = 'bin/jpgp-0.0.2-SNAPSHOT.jar';
openpgp.init();
function JPGP() {
this.args = [];
this.signature = "";
this.uid = "";
this.data = "";
this.noCarriage = false;
// PUBLIC
this.certificate = function(asciiArmored) {
this.args.push({opt: 'c', value: escape(asciiArmored)});
return this;
};
this.publicKey = function(asciiArmored) {
this.args.push({opt: 'p', value: escape(asciiArmored)});
openpgp.keyring.importPublicKey(asciiArmored);
return this;
};
this.signature = function(asciiArmored) {
this.args.push({opt: 's', value: escape(asciiArmored)});
return this;
this.certificate = function(asciiArmored) {
var cert = openpgp.read_publicKey(asciiArmored)[0];
var fpr = hexstrdump(cert.publicKeyPacket.getFingerprint()).toUpperCase();
var uids = [];
cert.userIds.forEach(function (uid) {
uids.push(uid.text);
});
return {
"fingerprint": fpr,
"uids": uids,
"raw": cert
};
};
this.uid = function(uid_string) {
this.args.push({opt: 'u', value: escape(uid_string)});
this.signature = function(asciiArmored) {
this.signature = asciiArmored;
return this;
};
this.data = function(data_string) {
this.args.push({opt: 'd', value: escape(data_string)});
this.data = data_string;
return this;
};
this.noCarriage = function() {
this.args.push({opt: 'n'});
this.noCarriage = true;
return this;
};
this.parse = function(callback) {
command('P', this.args, callback);
};
this.verify = function(callback) {
command('V', this.args, function (err, stdout, stderr) {
if(!err && !stderr){
var verified = JSON.parse(stdout).data;
if(verified){
callback();
}
else callback("Signature does not match.\n" + err + "\n" + stdout + "\n" + stderr);
}
else callback(err + "\n" + stderr);
});
var start = new Date();
// Do
var signatures = openpgp.read_message(this.signature);
var sig = signatures[2];
var verified = sig.verifySignature();
// Done
var end = new Date();
var diff = end.getTime() - start.getTime();
console.log("jpgp verify", diff + " ms");
if(verified){
callback();
}
else callback("Signature does not match.\n");
};
this.isSigned = function(callback) {
command('I', this.args, callback);
};
// PRIVATE
function escape(str) {
return '"' + str + '"';
}
function command(c, args, callback) {
var argsStr = "";
for (var i = 0; i < args.length; i++) {
argsStr += " -" + args[i].opt;
if(args[i].value){
argsStr += " " + args[i].value;
}
function hexstrdump(str) {
if (str == null)
return "";
var r=[];
var e=str.length;
var c=0;
var h;
while(c<e){
h=str[c++].charCodeAt().toString(16);
while(h.length<2) h="0"+h;
r.push(""+h);
}
call(c, argsStr, callback);
}
function call(c, args, callback) {
// var cmd = 'java -Xdebug -Xrunjdwp:transport=dt_socket,suspend=n,address=8044 -jar '+ JPGP_JAR + ' -' + c + args;
var cmd = 'java -jar '+ JPGP_JAR + ' -' + c + args;
var start = new Date();
exec(cmd, function (err, stdout, stderr) {
var end = new Date();
var diff = end.getTime() - start.getTime();
console.log("jpgp -" + c, diff + " ms");
callback(err, stdout, stderr);
});
}
return r.join('');
};
}
module.exports = function () {
......
......@@ -119,4 +119,17 @@ module.exports.express = {
onLoaded(err, app);
}.bind(this));
}
};
\ No newline at end of file
};
String.prototype.trim = function(){
return this.replace(/^\s+|\s+$/g, '');
};
String.prototype.unix2dos = function(){
return this.dos2unix().replace(/\n/g, '\r\n');
};
String.prototype.dos2unix = function(){
return this.replace(/\r\n/g, '\n');
};
This diff is collapsed.
var jpgp = require('../lib/jpgp');
var mongoose = require('mongoose');
var async = require('async');
var sha1 = require('sha1');
......@@ -63,7 +62,7 @@ AmendmentSchema.methods = {
callback("No amendment given");
return;
}
this.hash = sha1(rawAmend).toUpperCase();
this.hash = sha1(rawAmend.unix2dos()).toUpperCase();
var obj = this;
var captures = [
{prop: "version", regexp: /Version: (.*)/},
......@@ -239,7 +238,7 @@ AmendmentSchema.methods = {
for(var i = 0; i < this.membersChanges.length; i++){
raw += this.membersChanges[i] + "\n";
}
return raw;
return raw.unix2dos();
},
loadFromFile: function(file, done) {
......
......@@ -17,31 +17,24 @@ var PublicKeySchema = new Schema({
PublicKeySchema.methods = {
construct: function(done) {
var obj = this;
jpgp().certificate(obj.raw).parse(function (err, stdout, stderr) {
if(stderr)
sys.print('stderr: \n' + stderr);
if (err !== null) {
console.log('exec error: ' + err);
}
var k = JSON.parse(stdout).data;
obj.fingerprint = k.fingerprint;
var uid = k.uids[0].uid;
var extract = uid.match(/([\s\S]*) \(([\s\S]*)\) <([\s\S]*)>/);
if(extract && extract.length === 4){
var k = jpgp().certificate(obj.raw);
obj.fingerprint = k.fingerprint;
var uid = k.uids[0];
var extract = uid.match(/([\s\S]*) \(([\s\S]*)\) <([\s\S]*)>/);
if(extract && extract.length === 4){
obj.name = extract[1];
obj.comment = extract[2];
obj.email = extract[3];
}
else{
extract = uid.match(/([\s\S]*) <([\s\S]*)>/);
if(extract && extract.length === 3){
obj.name = extract[1];
obj.comment = extract[2];
obj.email = extract[3];
}
else{
extract = uid.match(/([\s\S]*) <([\s\S]*)>/);
if(extract && extract.length === 3){
obj.name = extract[1];
obj.comment = '';
obj.email = extract[2];
}
obj.comment = '';
obj.email = extract[2];
}
done(err);
});
}
done();
}
};
......
......@@ -7,9 +7,6 @@
"test": "test"
},
"scripts": {
"preupdate": "sh scripts/preupdate/jpgp jpgp-0.0.2-SNAPSHOT.jar",
"preinstall": "sh scripts/preinstall/jpgp jpgp-0.0.2-SNAPSHOT.jar",
"pretest": "sh scripts/preinstall/jpgp jpgp-0.0.2-SNAPSHOT.jar",
"test": "mocha test/*.js",
"start": "bin/nodecoin"
},
......
#!/bin/bash
# Checkout jpgp (Java module for PGP) from SCM, compiles it, and copies it to bin/ folder.
jar=$1
echo "jpgp - preinstall ($jar)"
jpgp_folder="mvn-jpgp"
if [ ! -e "bin/$jar" ]; then
rm -Rf "$jpgp_folder"
git clone --branch=master http://github.com/c-geek/jpgp.git "$jpgp_folder"
cd "$jpgp_folder"
mvn clean package
cp -v "target/$jar" "../bin/"
cd ../
rm -Rf "$jpgp_folder"
fi
\ No newline at end of file
#!/bin/bash
jar=$1
echo "jpgp - preupdate ($jar)"
if [ -e bin/$jar ]; then
rm "../bin/$jar"
fi
sh preinstall/jpgp $jar
\ No newline at end of file
......@@ -70,9 +70,9 @@ describe('Amendment', function(){
assert.equal(newVoters[2], "C73882B64B7E72237A2F460CE9CAB76D19A8651E");
});
it('its hash should be 6F4ACBC7A25A0AAB9B58778EAD5A297EF3E51D00', function(){
assert.equal(amTest.hash, '6F4ACBC7A25A0AAB9B58778EAD5A297EF3E51D00');
assert.equal(sha1(amTest.getRaw()).toUpperCase(), '6F4ACBC7A25A0AAB9B58778EAD5A297EF3E51D00');
it('its hash should be EE6046B38C5B496F2C3A96FBE2C28A29AE49CD9F', function(){
assert.equal(amTest.hash, 'EE6046B38C5B496F2C3A96FBE2C28A29AE49CD9F');
assert.equal(sha1(amTest.getRaw()).toUpperCase(), 'EE6046B38C5B496F2C3A96FBE2C28A29AE49CD9F');
});
});
......@@ -104,8 +104,8 @@ describe('Amendment', function(){
should.not.exist(amTest.coinMinPower);
});
it('should have 6F4ACBC7A25A0AAB9B58778EAD5A297EF3E51D00 previous hash', function(){
assert.equal(amTest.previousHash, '6F4ACBC7A25A0AAB9B58778EAD5A297EF3E51D00');
it('should have EE6046B38C5B496F2C3A96FBE2C28A29AE49CD9F previous hash', function(){
assert.equal(amTest.previousHash, 'EE6046B38C5B496F2C3A96FBE2C28A29AE49CD9F');
});
it('should have 0 new members', function(){
......@@ -119,6 +119,14 @@ describe('Amendment', function(){
assert.equal(newVoters.length, 0);
assert.equal(amTest.votersCount, 3);
});
it('its -self-computed- hash should be 0F45DFDA214005250D4D2CBE4C7B91E60227B0E5', function(){
assert.equal(amTest.hash, '0F45DFDA214005250D4D2CBE4C7B91E60227B0E5');
});
it('its -manually-computed- should be 0F45DFDA214005250D4D2CBE4C7B91E60227B0E5', function(){
assert.equal(sha1(amTest.getRaw()).toUpperCase(), '0F45DFDA214005250D4D2CBE4C7B91E60227B0E5');
});
});
describe('2 of beta_brousouf currency', function(){
......@@ -149,8 +157,8 @@ describe('Amendment', function(){
assert.equal(amTest.coinMinPower, 0);
});
it('should have 3E6EDD8CF1391AFADB3E3619B3A131E9300B963F previous hash', function(){
assert.equal(amTest.previousHash, '3E6EDD8CF1391AFADB3E3619B3A131E9300B963F');
it('should have 0F45DFDA214005250D4D2CBE4C7B91E60227B0E5 previous hash', function(){
assert.equal(amTest.previousHash, '0F45DFDA214005250D4D2CBE4C7B91E60227B0E5');
});
it('should have F92B6F81C85200250EE51783F5F9F6ACA57A9AFF members hash', function(){
......@@ -179,6 +187,14 @@ describe('Amendment', function(){
assert.equal(leavingVoters.length, 1);
assert.equal(amTest.votersCount, 2);
});
it('its -self-computed- hash should be 8E825DA77C1C2A7C655132C04389DF5411601923', function(){
assert.equal(amTest.hash, '8E825DA77C1C2A7C655132C04389DF5411601923');
});
it('its -manually-computed- should be 8E825DA77C1C2A7C655132C04389DF5411601923', function(){
assert.equal(sha1(amTest.getRaw()).toUpperCase(), '8E825DA77C1C2A7C655132C04389DF5411601923');
});
});
describe('2 (WRONG-UD ONE) of beta_brousouf currency', function(){
......
Version: 1
Currency: beta_brousouf
Number: 0
VotersRoot: F5ACFD67FC908D28C0CFDAD886249AC260515C90
VotersCount: 3
VotersChanges:
+2E69197FAB029D8669EF85E82457A1587CA0ED9C
+33BBFC0C67078D72AF128B5BA296CC530126F372
+C73882B64B7E72237A2F460CE9CAB76D19A8651E
MembersRoot: F5ACFD67FC908D28C0CFDAD886249AC260515C90
MembersCount: 3
MembersChanges:
+2E69197FAB029D8669EF85E82457A1587CA0ED9C
+33BBFC0C67078D72AF128B5BA296CC530126F372
+C73882B64B7E72237A2F460CE9CAB76D19A8651E
Version: 1
Currency: beta_brousouf
Number: 0
VotersRoot: F5ACFD67FC908D28C0CFDAD886249AC260515C90
VotersCount: 3
VotersChanges:
+2E69197FAB029D8669EF85E82457A1587CA0ED9C
+33BBFC0C67078D72AF128B5BA296CC530126F372
+C73882B64B7E72237A2F460CE9CAB76D19A8651E
MembersRoot: F5ACFD67FC908D28C0CFDAD886249AC260515C90
MembersCount: 3
MembersChanges:
+2E69197FAB029D8669EF85E82457A1587CA0ED9C
+33BBFC0C67078D72AF128B5BA296CC530126F372
+C73882B64B7E72237A2F460CE9CAB76D19A8651E
Version: 1
Currency: beta_brousouf
Number: 1
PreviousHash: 6F4ACBC7A25A0AAB9B58778EAD5A297EF3E51D00
VotersRoot: F5ACFD67FC908D28C0CFDAD886249AC260515C90
VotersCount: 3
VotersChanges:
MembersRoot: F5ACFD67FC908D28C0CFDAD886249AC260515C90
MembersCount: 3
MembersChanges:
Version: 1
Currency: beta_brousouf
Number: 1
PreviousHash: EE6046B38C5B496F2C3A96FBE2C28A29AE49CD9F
VotersRoot: F5ACFD67FC908D28C0CFDAD886249AC260515C90
VotersCount: 3
VotersChanges:
MembersRoot: F5ACFD67FC908D28C0CFDAD886249AC260515C90
MembersCount: 3
MembersChanges:
Version: 1
Currency: beta_brousouf
Number: 2
PreviousHash: 3E6EDD8CF1391AFADB3E3619B3A131E9300B963F
UniversalDividend: 100
CoinMinimalPower: 0
VotersRoot: DC7A9229DFDABFB9769789B7BFAE08048BCB856F
VotersCount: 2
VotersChanges:
-C73882B64B7E72237A2F460CE9CAB76D19A8651E
MembersRoot: F92B6F81C85200250EE51783F5F9F6ACA57A9AFF
MembersCount: 4
MembersChanges:
+31A6302161AC8F5938969E85399EB3415C237F93
Version: 1
Currency: beta_brousouf
Number: 2
PreviousHash: 0F45DFDA214005250D4D2CBE4C7B91E60227B0E5
UniversalDividend: 100
CoinMinimalPower: 0
VotersRoot: DC7A9229DFDABFB9769789B7BFAE08048BCB856F
VotersCount: 2
VotersChanges:
-C73882B64B7E72237A2F460CE9CAB76D19A8651E
MembersRoot: F92B6F81C85200250EE51783F5F9F6ACA57A9AFF
MembersCount: 4
MembersChanges:
+31A6302161AC8F5938969E85399EB3415C237F93
Version: 1
Currency: beta_brousouf
Number: 2
PreviousHash: 3E6EDD8CF1391AFADB3E3619B3A131E9300B963F
UniversalDividend: 122
CoinMinimalPower: 3
VotersRoot: DC7A9229DFDABFB9769789B7BFAE08048BCB856F
VotersCount: 2
VotersChanges:
-C73882B64B7E72237A2F460CE9CAB76D19A8651E
MembersRoot: D092366E448D18C0E72D7C7976A647A122B55225
MembersCount: 4
MembersChanges:
+31A6302161AC8F5938969E85399EB3415C237F93
Version: 1
Currency: beta_brousouf
Number: 2
PreviousHash: 3E6EDD8CF1391AFADB3E3619B3A131E9300B963F
UniversalDividend: 122
CoinMinimalPower: 3
VotersRoot: DC7A9229DFDABFB9769789B7BFAE08048BCB856F
VotersCount: 2
VotersChanges:
-C73882B64B7E72237A2F460CE9CAB76D19A8651E
MembersRoot: D092366E448D18C0E72D7C7976A647A122B55225
MembersCount: 4
MembersChanges:
+31A6302161AC8F5938969E85399EB3415C237F93
Version: 1
Currency: beta_brousouf
Number: 2
PreviousHash: 3E6EDD8CF1391AFADB3E3619B3A131E9300B963F
UniversalDividend: 100
CoinMinimalPower: 0
VotersRoot: 2E69197FAB029D8669EF85E82457A1587CA0ED9C
VotersCount: 1
VotersChanges:
-33BBFC0C67078D72AF128B5BA296CC530126F372
-C73882B64B7E72237A2F460CE9CAB76D19A8651E
MembersRoot: F92B6F81C85200250EE51783F5F9F6ACA57A9AFF
MembersCount: 4
MembersChanges:
+31A6302161AC8F5938969E85399EB3415C237F93
Version: 1
Currency: beta_brousouf
Number: 2
PreviousHash: 3E6EDD8CF1391AFADB3E3619B3A131E9300B963F
UniversalDividend: 100
CoinMinimalPower: 0
VotersRoot: 2E69197FAB029D8669EF85E82457A1587CA0ED9C
VotersCount: 1
VotersChanges:
-33BBFC0C67078D72AF128B5BA296CC530126F372
-C73882B64B7E72237A2F460CE9CAB76D19A8651E
MembersRoot: F92B6F81C85200250EE51783F5F9F6ACA57A9AFF
MembersCount: 4
MembersChanges:
+31A6302161AC8F5938969E85399EB3415C237F93
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.12 (GNU/Linux)
mQENBFHHC/EBCADWTLSN7EGP+n30snndS3ZNcB02foL+0opcS6LK2coPDJLg2noo
keJRHZxF3THmZQrKwZOjiuDBinOc5DWlzIS/gD/RaXwntgPFlGKBlBU+g255fr28
ziSb5Y1lW4N//nUFdPZzoMmPgRj0b17T0UPCoMR8ZZ/Smk5LINbQwt+A+LEoxEdE
Vcq+Tyc0OlEabqO6RFqiKDRiPhGPiCwVQA3yPjb6iCp5gTchObCxCnDbxA0Mfj9F
mHrGbepNHGXxStO4xT0woCb7y02S1E8K08kOc5Bq9e1Yj5I/mdaw4Hn/Wp28lZl1
mnO1u1z9ZU/rcglhEyaEOTwasheb44QcdGSfABEBAAG0TUxvTCBDYXQgKHVkaWQy
O2M7Q0FUO0xPTDsyMDAwLTA0LTE5O2UrNDMuNzAtMDc5LjQyOzA7KSA8Y2VtLm1v
cmVhdUBnbWFpbC5jb20+iQE9BBMBCAAnBQJRxwvxAhsDBQkLR5jvBQsJCAcDBRUK
CQgLBRYCAwEAAh4BAheAAAoJEOnKt20ZqGUeZYcH/0ItH4b/O0y7V1Jzc1DZAdn4
iDiI7/SF3fN4f6cJCu/SOVb+ERFIb6JK+HNHdVAcMHKaPW625R0FahHUkcXWkkGm
Q6+sLIsVZwVN1oeZtlD12cq9A4UJyfJUXkinMKkI8xpdV8J7s5wFRavOS/qaF5be
ah0Z+IGwQK0nuXxWpT6UZWbpUfXPQB2Mz2/rpjSWKwO3X4FwwOfDiuZExyH2JPDY
shdPcj/x+gnzYW9XfWCJw3rOK42vtM+aLtUpJO0Jh6X/sj/iqyS4rPB4DVCmEgSX
Px1P+kqnsz3aNTOIujXS8Faz+TC+eNhn+z3SoTl5gBlNNM171fWFr0BR3nIfIu65
AQ0EUccL8QEIAPAQaxK6s4DjDHiOwrMotvb479QD5PsHU6S0VG0+naoPlNJb2d5w
YhnFAn4aYLiXx4IIl38rHnV+yWATOUe2rdCe4enTXkxyWJVaxIcNJLFpUjHYGbrC
nNwiXpuQfSDuRN/wcVNSBKXhWNUPY9IsbgERWhS5YTFnuQcBjMqDwF6JImQ8O4nZ
wno811nqK1XaMuLVvXZAsO1Vi1k3NArM5+jdlq9e3BA0NcHJmGEcQdTw0Tk5Oq6r
mE8ux7pS0bn6OUkkseR5DyRlFtzqi4wp30GeggeFExx7ZCVuctpJX9ZoC3cJoZT0
s3LuUtV0EW50yCtP+3Vpkek2WtjfVbM6kDkAEQEAAYkBJQQYAQgADwUCUccL8QIb
DAUJC0eY7wAKCRDpyrdtGahlHg7+B/95xEoSrFQ7/mc7g6sbisvx3s547gUXXYSu
FHS03IMDWJrfGKqXtBf9ETBx4OLeBXY7z1lL4WCN6/xtrL+mSQ9dbDqdXv/1EhkS
v0s+IvJ34KYGAkFXSCoTE7rnkPwQjoMYVSFkf5e8g9adyKvndq/QSPNuv+FPL6sH
m1N9nmus5Ebr0zTVDmmfoqzokuDfHm5h6YrkFscMGjrCKWuXSiTaGj9Hm3MqeZ3T
Kva5isa/h0h7Ai3wJ5XJpMrFNN6BU/wIt7fM2hsNAOwaG+WUfgjYEkOua8gPPtpL
ZJJPb/89yrs9F7JkLi/oiAl5VpItm+hlFpLe1TE7oa6k53eZ2a+V
=rOj9
-----END PGP PUBLIC KEY BLOCK-----
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.12 (GNU/Linux)
mQENBFHHC/EBCADWTLSN7EGP+n30snndS3ZNcB02foL+0opcS6LK2coPDJLg2noo
keJRHZxF3THmZQrKwZOjiuDBinOc5DWlzIS/gD/RaXwntgPFlGKBlBU+g255fr28
ziSb5Y1lW4N//nUFdPZzoMmPgRj0b17T0UPCoMR8ZZ/Smk5LINbQwt+A+LEoxEdE
Vcq+Tyc0OlEabqO6RFqiKDRiPhGPiCwVQA3yPjb6iCp5gTchObCxCnDbxA0Mfj9F
mHrGbepNHGXxStO4xT0woCb7y02S1E8K08kOc5Bq9e1Yj5I/mdaw4Hn/Wp28lZl1
mnO1u1z9ZU/rcglhEyaEOTwasheb44QcdGSfABEBAAG0TUxvTCBDYXQgKHVkaWQy
O2M7Q0FUO0xPTDsyMDAwLTA0LTE5O2UrNDMuNzAtMDc5LjQyOzA7KSA8Y2VtLm1v
cmVhdUBnbWFpbC5jb20+iQE9BBMBCAAnBQJRxwvxAhsDBQkLR5jvBQsJCAcDBRUK
CQgLBRYCAwEAAh4BAheAAAoJEOnKt20ZqGUeZYcH/0ItH4b/O0y7V1Jzc1DZAdn4
iDiI7/SF3fN4f6cJCu/SOVb+ERFIb6JK+HNHdVAcMHKaPW625R0FahHUkcXWkkGm
Q6+sLIsVZwVN1oeZtlD12cq9A4UJyfJUXkinMKkI8xpdV8J7s5wFRavOS/qaF5be
ah0Z+IGwQK0nuXxWpT6UZWbpUfXPQB2Mz2/rpjSWKwO3X4FwwOfDiuZExyH2JPDY
shdPcj/x+gnzYW9XfWCJw3rOK42vtM+aLtUpJO0Jh6X/sj/iqyS4rPB4DVCmEgSX
Px1P+kqnsz3aNTOIujXS8Faz+TC+eNhn+z3SoTl5gBlNNM171fWFr0BR3nIfIu65
AQ0EUccL8QEIAPAQaxK6s4DjDHiOwrMotvb479QD5PsHU6S0VG0+naoPlNJb2d5w
YhnFAn4aYLiXx4IIl38rHnV+yWATOUe2rdCe4enTXkxyWJVaxIcNJLFpUjHYGbrC
nNwiXpuQfSDuRN/wcVNSBKXhWNUPY9IsbgERWhS5YTFnuQcBjMqDwF6JImQ8O4nZ
wno811nqK1XaMuLVvXZAsO1Vi1k3NArM5+jdlq9e3BA0NcHJmGEcQdTw0Tk5Oq6r
mE8ux7pS0bn6OUkkseR5DyRlFtzqi4wp30GeggeFExx7ZCVuctpJX9ZoC3cJoZT0
s3LuUtV0EW50yCtP+3Vpkek2WtjfVbM6kDkAEQEAAYkBJQQYAQgADwUCUccL8QIb
DAUJC0eY7wAKCRDpyrdtGahlHg7+B/95xEoSrFQ7/mc7g6sbisvx3s547gUXXYSu
FHS03IMDWJrfGKqXtBf9ETBx4OLeBXY7z1lL4WCN6/xtrL+mSQ9dbDqdXv/1EhkS
v0s+IvJ34KYGAkFXSCoTE7rnkPwQjoMYVSFkf5e8g9adyKvndq/QSPNuv+FPL6sH
m1N9nmus5Ebr0zTVDmmfoqzokuDfHm5h6YrkFscMGjrCKWuXSiTaGj9Hm3MqeZ3T
Kva5isa/h0h7Ai3wJ5XJpMrFNN6BU/wIt7fM2hsNAOwaG+WUfgjYEkOua8gPPtpL
ZJJPb/89yrs9F7JkLi/oiAl5VpItm+hlFpLe1TE7oa6k53eZ2a+V
=rOj9
-----END PGP PUBLIC KEY BLOCK-----
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1.4.12 (GNU/Linux)
owGbwMvMwMG4aNqZYEa1z0WMaxkfJnE6Oek6+hro+nsHvv7WF5ZaVJyZn2elYMjl
XFpUlJqXXGmlkJRakhifVJRfWpxfmsblV5qblFpkpWDAFZZfAlQelJ9fYqXgZuro
7OZiZu7mbGlg4WJk4WwA5Dq6WFiYGZlYOjobmRmYGpoC5aCanPNL84C6jGHcjMS8
9NRiKy5tI1czS0NLczdHJwMjSxcLMzNLVzcLU1cLIxNTc0dDUwtzZ0cDVxdLZy5t
Y2MnJzegNWbmBuYWLuZGjm6GRhZOpk6ORpZmzs6mxgaGRmZuxuZGXNrO5sYWFkZO
ZiZO5q7mRkbG5o5GbiZmBs6uls6OTuZmLoaWjhZmpoauXL6pIK+R6iOoLriXYPzB
4adOxjksDIwcDGysTKAIZuDiFIDFv7EYD8PyrBeLN2lsW7E17u6StxOqnu6q1u+O
Kyq+vfSL8MWtgnt1/oUZ3Ltr3p5qwTzHvzB54aRLDXxLW0N/OIY6X7ij+Dz5ybyp
XIJfAhiYnhUe9vvFlzX5ohrf069fq8Ju3NycY7Rmqazjys12AaXXOYQEPtUb7Oeq
d8gLDjv65wXv7g7Z8ArLhMq9u5vquFJznda+9Lc9oaf1t/abXQBfl5iiWpCrr4n7
rqDjxx/MXF8fu9e24dd2u/NMNbVTb/E4L2nSkYz4vusVe+obWa8Tq26+KfjoEy6d
snu5rXLbbAPjt/lHuFu/Nh29szljVa8KJ4eUtfy9lUZWoYU/N72riv0y6+a1D44K
HqwN/qc13OvUo05e9WCymrG8tPFQ64Y2qzM+odoxk3boi9saHevbWSYw0cfqgvO2
u+xzS6xE2h4Jnzw3Z09AHINHS/fCQk31vZd6ip/tN9XKL+Sp2yp+pWjev7as2b28
s4XbD+h2t+fXZz+1fbK+4zEzS2i/XXWs01kfYcOzNgv+Xgi4ulJAY3OxbuFxAA==
=86x1
owGbwMvMwMG4aNqZYEa1z0WMaxk/JHE6Oek6+hro+nsH/oyRDkstKs7Mz7NSMOTl
ci4tKkrNS660UkhKLUmMTyrKLy3OL03j5fIrzU1KLbJSMODlCssvAeoIys8vsVJw
M3V0dnMxM3dztjSwcDGycDYAch1dLCzMjEwsHZ2NzAxMDU2BcjBdzvmleUBtxnB+
RmJeemqxFS+XtpGrmaWhpbmbo5OBkaWLhZmZpaubhamrhZGJqbmjoamFubOjgauL
pTNQqbGxk5Mb0CozcwNzCxdzI0c3QyMLJ1MnRyNLM2dnU2MDQyMzN2NzI6BSZ3Nj
CwsjJzMTJ3NXcyMjY3NHIzcTMwNnV0tnRydzMxdDS0cLM1NDV14u31SQD0n2F1Qb
wmMwgcHjs07GOSwMjBwMbKxMoPhm4OIUgCWHBCfu/wEzuKQnFh7RqTczNUmb3zz3
w5LK57cddh7aneC3cd00a2srFhVnn4ZXmtV/Y8TUhWU+fk2ZwOYl8rqmQNpVY/nv
gLTYtHVPJz3qVGYzeiv+1/Kk2pVu/qJ+i+5SLo0TWXwnl+vZKbWKh6e1fZmn/5NB
q954RyCbRb387wXm3xzyV1v7LTCq+nTN6Kv8yo+3z3HLXJbhdvt4ps7l+sumvtVV
VydlzF+wLDytYPKBSVYHOhj75gjF2k5RPamzX89iVWPgs5SetxcllR1DEqbtvnjj
n2VsvKml7vOAKS3T2zckdccuYj/KbcBWcSF1g9yTx5eTN/75kSZl47jLx+yvcGdO
XOokoezP5Z+cOo+95tOqNrozqcTG7/aLpq755cENsV/kymsmWudrRLVfZL3NLV/q
kfNEgk3kkmL2pZpZXX6P2lQPs+/i0Ndb90zxzb7+253Zd+I4krepvg2ceStylZDk
hAt+cjd2TGnYkLNxRqRiFNd3puUCr/VZXW+XuW+rWtpm2v19j5am2+o8m+lbtE5E
rAYA
=yzLT
-----END PGP MESSAGE-----
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1.4.12 (GNU/Linux)
owGbwMvMwMH48tT2XMkVqXKMaxkfJnE6Oek6+hro+nsHvv56PSy1qDgzP89KwZDL
ubSoKDUvudJKISm1JDE+qSi/tDi/NI3LrzQ3KbXISsGAKyy/BKg8KD+/xErBzdTR
2c3FzNzN2dLAwsXIwtkAyHV0sbAwMzKxdHQ2MjMwNTQFykE1OeeX5gF1GcO4GYl5
6anFVlzaRq5mloaW5m6OTgZGli4WZmaWrm4Wpq4WRiam5o6Gphbmzo4Gri6Wzlza
xsZOTm5Aa8zMDcwtXMyNHN0MjSycTJ0cjSzNnJ1NjQ0MjczcjM2NuLSdzY0tLIyc
zEyczF3NjYyMzR2N3EzMDJxdLZ0dnczNXAwtHS3MTA1duXxTQV4j1UdQXXAvwfiD
w0+djDIsDIwcDGysTKAIZuDiFIDF//fH7H84StbesVm2OsWg9rLzE06eWlmWfysu
buyce1l/1ct7i5aciH728kixYkHNCs1t+znO3zdaJqL1i2dv8qeixOPBZ/JuCzR3
rTR9bxYkvFctyevUKbmlnqmbcvhZEssS/OTKo784zBfM2jw1nMnxnI6BgNfkuMRz
fy8pCFcLL4ubZ6x/+07Nx2Y5tUMMm34+EdR70d90SYxv1bG5zBERkz3c7DvNr9Q/
23xxuaqB44Oc3/kFwcGFC2rXl6c9t+l69Sbn+5SrkV4yyv/uHZ+7L8diZ8evf28W
zWWv3rv719w5qf9nqX2UFfl7qjTx8DnO74nmzIy8s8Un6s49kcMt+/2v+t3TE2JW
XfQ2WLs/68xxAA==
=oZ2h
owGbwMvMwMH48tT2XMkVqXKMaxk/JHE6Oek6+hro+nsH/rSSCEstKs7Mz7NSMOTl
ci4tKkrNS660UkhKLUmMTyrKLy3OL03j5fIrzU1KLbJSMODlCssvAeoIys8vsVJw
M3V0dnMxM3dztjSwcDGycDYAch1dLCzMjEwsHZ2NzAxMDU2BcjBdzvmleUBtxnB+
RmJeemqxFS+XtpGrmaWhpbmbo5OBkaWLhZmZpaubhamrhZGJqbmjoamFubOjgauL
pTNQqbGxk5Mb0CozcwNzCxdzI0c3QyMLJ1MnRyNLM2dnU2MDQyMzN2NzI6BSZ3Nj