diff --git a/app/models/publickey.js b/app/models/publickey.js new file mode 100644 index 0000000000000000000000000000000000000000..ed98fd3cbc75d3bf7c5a054697f7424cc5f21895 --- /dev/null +++ b/app/models/publickey.js @@ -0,0 +1,116 @@ +var jpgp = require('../../lib/jpgp'); +var mongoose = require('mongoose'); +var async = require('async'); +var _ = require('underscore'); +var Schema = mongoose.Schema; + +var PublicKeySchema = new Schema({ + raw: String, + fingerprint: String, + name: String, + email: String, + comment: String, + created: Date, + updated: Date +}); + +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){ + 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]; + } + } + done(err); + }); + } +}; + +PublicKeySchema.statics.search = function (motif, done) { + var obj = this; + var found = []; + var fprPattern = motif.match(/^0x(.*)$/); + var searchByUID = { + byName: function(callback){ + obj.find({ name: new RegExp(motif, 'i')}, function (err, keys) { + found.push(keys); + callback(); + }); + }, + byEmail: function(callback){ + obj.find({ email: new RegExp(motif, 'i')}, function (err, keys) { + found.push(keys); + callback(); + }); + }, + byComment: function(callback){ + obj.find({ comment: new RegExp(motif, 'i')}, function (err, keys) { + found.push(keys); + callback(); + }); + } + }; + var searchByFingerprint = { + byFingerprint: function (callback) { + var fpr = fprPattern ? fprPattern[1] : ""; + obj.find({ fingerprint: new RegExp(fpr, 'i')}, function (err, keys) { + found.push(keys); + callback(); + }); + } + }; + var searchFunc = fprPattern ? searchByFingerprint : searchByUID; + async.parallel(searchFunc, function(err) { + var pubKeys = {}; + var foundKeys = _(found).flatten(); + async.each(foundKeys, function (key, done) { + pubKeys[key.id] = key; + done(); + }, function (err) { + done(err, _(pubKeys).values()); + }); + }); +}; + +PublicKeySchema.statics.verify = function (asciiArmored, signature, done) { + jpgp() + .publicKey(asciiArmored) + .data(asciiArmored) + .noCarriage() + .signature(signature) + .verify(function (err, stdout, stderr) { + if(!err && !stderr){ + var verified = JSON.parse(stdout).data; + if(verified){ + done(); + } + else{ + done("Signature does not match.\n" + err + "\n" + stdout + "\n" + stderr); + } + } + else{ + done(err + "\n" + stderr); + } + }); +}; + +var PublicKey = mongoose.model('PublicKey', PublicKeySchema); \ No newline at end of file