Commit b5341b7884d950c13e5fc0ff8d0292ec9d8f27d6
basic implementation
Dominic Tarr committed on 3/14/2018, 7:07:32 AMParent: 5ecb8053cf15f8acb7d0a7b2feca91ff3adea6de
Files changed
index.js | added |
index.js | |||
---|---|---|---|
@@ -1,0 +1,88 @@ | |||
1 … | +var ssbKeys = require('ssb-keys') | ||
2 … | + | ||
3 … | +var chloride = require('chloride') | ||
4 … | + | ||
5 … | +function box (data, key) { | ||
6 … | + var b = new Buffer(JSON.stringify(data)) | ||
7 … | + return chloride.crypto_secretbox_easy(b, key.slice(0, 24), key).toString('base64') | ||
8 … | +} | ||
9 … | + | ||
10 … | +function unbox (ctxt, key) { | ||
11 … | + //var b = new Buffer(JSON.stringify(data)) | ||
12 … | + var b = new Buffer(ctxt, 'base64') | ||
13 … | + var ptxt = chloride.crypto_secretbox_open_easy(b, key.slice(0, 24), key) | ||
14 … | + if(!ptxt) return | ||
15 … | + try { | ||
16 … | + return JSON.parse(ptxt) | ||
17 … | + } catch(err) { | ||
18 … | + console.error(err) | ||
19 … | + } | ||
20 … | +} | ||
21 … | + | ||
22 … | + | ||
23 … | +function hash(s) { | ||
24 … | + return chloride.crypto_hash_sha256(new Buffer(s, 'utf8')) | ||
25 … | +} | ||
26 … | + | ||
27 … | +exports.createInvite = function (seed, id, reveal, private) { | ||
28 … | + var keys = ssbKeys.generate(null, seed) //K | ||
29 … | + return ssbKeys.signObj(keys, null, { | ||
30 … | + type: 'invite', | ||
31 … | + invite: keys.id, | ||
32 … | + host: id, //sign our own key, to prove we created K | ||
33 … | + reveal: box(reveal, hash(hash(seed))), | ||
34 … | + private: box(private, hash(seed)) | ||
35 … | + }) | ||
36 … | +} | ||
37 … | + | ||
38 … | +exports.verifyInvitePublic = function (msg) { | ||
39 … | + if(!ssbKeys.verifyObj(msg.content.invite, msg.content)) throw new Error('invalid guest signature') | ||
40 … | + if(!ssbKeys.verifyObj(msg.author, msg)) throw new Error('invalid host signature') | ||
41 … | + return true | ||
42 … | +} | ||
43 … | + | ||
44 … | +exports.verifyInvitePrivate = function (msg, seed) { | ||
45 … | + exports.verifyInvitePublic(msg) | ||
46 … | + if(msg.content.reveal) { | ||
47 … | + var reveal = unbox(msg.content.reveal, hash(hash(seed))) | ||
48 … | + if(!reveal) throw new Error('could not decrypt message to be revealed') | ||
49 … | + } | ||
50 … | + if(msg.content.private) { | ||
51 … | + var private = unbox(msg.content.private, hash(seed)) | ||
52 … | + if(!reveal) throw new Error('could not decrypt private message') | ||
53 … | + } | ||
54 … | + return {reveal: reveal, private: private} | ||
55 … | +} | ||
56 … | + | ||
57 … | +exports.createAccept = function (msg, seed, id) { | ||
58 … | + var keys = ssbKeys.generate(null, seed) //K | ||
59 … | + if(keys.id != msg.content.invite) throw new Error('seed does not match invite') | ||
60 … | + | ||
61 … | + var inviteId = ssbKeys.hash(JSON.stringify(msg, null, 2)) | ||
62 … | + return ssbKeys.signObj(keys, null, { | ||
63 … | + reciept: inviteId, | ||
64 … | + id: id, | ||
65 … | + key: msg.content.reveal ? hash(hash(seed)).toString('base64') : undefined | ||
66 … | + }) | ||
67 … | +} | ||
68 … | + | ||
69 … | +exports.verifyAccept = function (accept, invite) { | ||
70 … | + console.log(accept, invite) | ||
71 … | + var reveal | ||
72 … | + if(ssbKeys.hash(JSON.stringify(invite, null, 2)) !== accept.content.reciept) | ||
73 … | + throw new Error('acceptance not matched to given invite') | ||
74 … | + if(invite.content.reveal) { | ||
75 … | + reveal = unbox(invite.content.reveal, new Buffer(accept.content.key, 'base64')) | ||
76 … | + if(!reveal) throw new Error('accept did not correctly reveal invite') | ||
77 … | + } | ||
78 … | + | ||
79 … | + if(!ssbKeys.verifyObj(invite.content.invite, accept.content)) | ||
80 … | + throw new Error('did not verify invite-acceptance contents') | ||
81 … | + if(!ssbKeys.verifyObj(accept.content.id, accept)) | ||
82 … | + throw new Error('acceptance must be signed by claimed key') | ||
83 … | + return reveal || true | ||
84 … | +} | ||
85 … | + | ||
86 … | + | ||
87 … | + | ||
88 … | + |
Built with git-ssb-web