git ssb

0+

Dominic / ssb-peer-invites



Tree: 39b9c70c0e6cbb27bccacdc189c8a2f197e9959d

Files: 39b9c70c0e6cbb27bccacdc189c8a2f197e9959d / index.js

3289 bytesRaw
1var ssbKeys = require('ssb-keys')
2
3var chloride = require('chloride')
4
5function box (data, key) {
6 if(!data) return
7 var b = new Buffer(JSON.stringify(data))
8 return chloride.crypto_secretbox_easy(b, key.slice(0, 24), key).toString('base64')
9}
10
11function unbox (ctxt, key) {
12 //var b = new Buffer(JSON.stringify(data))
13 var b = new Buffer(ctxt, 'base64')
14 var ptxt = chloride.crypto_secretbox_open_easy(b, key.slice(0, 24), key)
15 if(!ptxt) return
16 try {
17 return JSON.parse(ptxt)
18 } catch(err) {
19 console.error(err)
20 }
21}
22
23
24function hash(s) {
25 return chloride.crypto_hash_sha256(
26 'string' == typeof s ? new Buffer(s, 'utf8') : s
27 )
28}
29
30var invite_key = hash("user-invites:development")
31
32exports.createInvite = function (seed, host, reveal, private) {
33 var keys = ssbKeys.generate(null, seed) //K
34 if(keys.id === host)
35 throw new Error('do not create invite with own public key')
36 return ssbKeys.signObj(keys, invite_key, {
37 type: 'invite',
38 invite: keys.id,
39 host: host, //sign our own key, to prove we created K
40 reveal: box(reveal, hash(hash(seed))),
41 private: box(private, hash(seed))
42 })
43}
44
45exports.verifyInvitePublic = function (msg) {
46 if(!ssbKeys.verifyObj(msg.content.invite, invite_key, msg.content))
47 throw new Error('invalid guest signature')
48 if(msg.content.host != msg.author)
49 throw new Error('host did not match author')
50
51 //an ordinary message so doesn't use special hmac_key
52 if(!ssbKeys.verifyObj(msg.author, msg))
53 throw new Error('invalid host signature')
54 return true
55}
56
57exports.verifyInvitePrivate = function (msg, seed) {
58 exports.verifyInvitePublic(msg)
59 if(msg.content.reveal) {
60 var reveal = unbox(msg.content.reveal, hash(hash(seed)))
61 if(!reveal) throw new Error('could not decrypt message to be revealed')
62 }
63 if(msg.content.private) {
64 var private = unbox(msg.content.private, hash(seed))
65 if(!reveal) throw new Error('could not decrypt private message')
66 }
67
68 return {reveal: reveal, private: private}
69}
70
71exports.createAccept = function (msg, seed, id) {
72 var keys = ssbKeys.generate(null, seed) //K
73 if(keys.id != msg.content.invite) throw new Error('seed does not match invite')
74 var inviteId = '%'+ssbKeys.hash(JSON.stringify(msg, null, 2))
75 return ssbKeys.signObj(keys, invite_key, {
76 type: 'invite/accept',
77 reciept: inviteId,
78 id: id,
79 key: msg.content.reveal ? hash(hash(seed)).toString('base64') : undefined
80 })
81}
82
83exports.verifyAccept = function (accept, invite) {
84 var reveal
85 if('%'+ssbKeys.hash(JSON.stringify(invite, null, 2)) !== accept.content.reciept)
86 throw new Error('acceptance not matched to given invite')
87 if(accept.author === invite.content.id)
88 throw new Error('invitee must use a new key, not the same seed')
89 if(invite.content.reveal) {
90 reveal = unbox(invite.content.reveal, new Buffer(accept.content.key, 'base64'))
91 if(!reveal) throw new Error('accept did not correctly reveal invite')
92 }
93
94 if(!ssbKeys.verifyObj(invite.content.invite, invite_key, accept.content))
95 throw new Error('did not verify invite-acceptance contents')
96 //an ordinary message, so does not use hmac_key
97 if(!ssbKeys.verifyObj(accept.content.id, accept))
98 throw new Error('acceptance must be signed by claimed key')
99 return reveal || true
100}
101
102

Built with git-ssb-web