git ssb

0+

Dominic / ssb-peer-invites



Tree: 4b01dccf7446ceaacbb44af829f67f0739b9c46d

Files: 4b01dccf7446ceaacbb44af829f67f0739b9c46d / index.js

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

Built with git-ssb-web