Files: 6c83ee92da37bbfea7f2b10e9bcca736b1447248 / test / group.js
4181 bytesRaw
1 | var chloride = require('chloride') |
2 | var crypto = require('crypto') |
3 | var tape = require('tape') |
4 | var group_box = require('group-box') |
5 | var u = require('../util') |
6 | var ssbKeys = require('ssb-keys') |
7 | |
8 | var Scuttlebot = require('ssb-server') |
9 | .use(require('../')) |
10 | |
11 | function hash (s) { |
12 | return chloride.crypto_hash_sha256(Buffer.from(s, 'utf8')) |
13 | } |
14 | |
15 | var alice = Scuttlebot({ |
16 | temp: true, |
17 | keys: ssbKeys.generate(null, hash('alice_secret1')) |
18 | }) |
19 | |
20 | var bob = alice.createFeed(ssbKeys.generate(null, hash('bob_secret1'))) |
21 | |
22 | function generate (seed) { |
23 | var keys = chloride.crypto_box_seed_keypair(seed) |
24 | return { |
25 | public: keys.publicKey.toString('base64')+'.curve25519', |
26 | private: keys.secretKey.toString('base64') |
27 | } |
28 | } |
29 | |
30 | function toBuffer(s) { |
31 | return Buffer.isBuffer(s) ? s : Buffer.from(s, 'base64') |
32 | } |
33 | |
34 | function scalarmult (pk,sk) { |
35 | return chloride.crypto_scalarmult(toBuffer(pk), toBuffer(sk)) |
36 | } |
37 | var alice_keys = generate(hash('alice_secret2')) |
38 | var bob_keys = generate(hash('bob_secret2')) |
39 | |
40 | var alice_prev, bob_prev |
41 | |
42 | tape('first message cannot be encrypted', function (t) { |
43 | alice.privateGroups.addCurvePair(alice_keys, function (err) { |
44 | if(err) throw err |
45 | alice.publish({ |
46 | type: 'private-msg-key', |
47 | key: alice_keys.public |
48 | }, function (err, data) { |
49 | if(err) throw err |
50 | alice_prev = data.key |
51 | bob.publish({ |
52 | type: 'private-msg-key', |
53 | key: bob_keys.public |
54 | }, function (err, data) { |
55 | bob_prev = data.key |
56 | if(err) throw err |
57 | t.end() |
58 | }) |
59 | }) |
60 | }) |
61 | }) |
62 | |
63 | function encrypt (content, prev, keys) { |
64 | return group_box.box( |
65 | Buffer.from(JSON.stringify(content), 'utf8'), |
66 | Buffer.isBuffer(prev) ? prev : u.id2Buffer(prev), |
67 | keys |
68 | ).toString('base64')+'.box2' |
69 | } |
70 | |
71 | tape('bob creates a group', function (t) { |
72 | var content = { |
73 | type: 'event', |
74 | text: "alice's surprise birthday" |
75 | } |
76 | //hot wiring group_box here! |
77 | //todo: make group-box fully deterministic, so payload_key |
78 | //may be passed in. |
79 | var en_key = crypto.randomBytes(32) |
80 | var ctxt = encrypt(content, bob_prev, [en_key]) |
81 | var nonce = u.id2Buffer(bob_prev) |
82 | var group_key = group_box.unboxKey(u.ctxt2Buffer(ctxt), nonce, [en_key], 8) |
83 | |
84 | t.notEqual(group_key, en_key) |
85 | t.ok(group_key, 'message can be decrypted') |
86 | |
87 | //create a group |
88 | bob.publish( |
89 | ctxt, |
90 | function (err, data) { |
91 | if(err) throw err |
92 | t.ok(data.key) |
93 | var group_id = data.key |
94 | nonce = u.id2Buffer(data.key) |
95 | var theme = { |
96 | type:'post', text: 'Theme: dress up as your favorite TLA' |
97 | } |
98 | //a message for the group |
99 | bob.publish(encrypt(theme, data.key, [ |
100 | u.hmac(Buffer.concat([nonce, u.id2Buffer(group_id)]), group_key) |
101 | ]), function (err, data) { |
102 | if(err) throw err |
103 | var msg_in_group = data.key |
104 | |
105 | var group_msg_key = u.hmac(Buffer.concat([nonce, u.id2Buffer(group_id)]), group_key) |
106 | var keys = [bob_keys, alice_keys].map(function (key) { |
107 | return scalarmult(bob_keys.private, key.public) |
108 | }) |
109 | |
110 | //message inviting alice to the group |
111 | bob.publish( |
112 | encrypt({ |
113 | type: 'entrust', |
114 | group: group_id, |
115 | unbox: group_key.toString('base64') |
116 | }, data.key, keys.concat([group_msg_key])), |
117 | function (err, data) { |
118 | if(err) throw err |
119 | var invite_id = data.key |
120 | t.ok(data) |
121 | alice.get({id: invite_id, private: true}, function (err, msg) { |
122 | if(err) throw err |
123 | t.equal(msg.content.group, group_id) |
124 | t.equal(msg.content.unbox, group_key.toString('base64')) |
125 | alice.privateGroups.addGroupKey({ |
126 | id: msg.content.group, |
127 | unbox: msg.content.unbox |
128 | }, function (err) { |
129 | if(err) throw err |
130 | alice.get({private: true, id: msg_in_group}, function (err, msg) { |
131 | if(err) throw err |
132 | t.deepEqual(msg.content, theme) |
133 | t.end() |
134 | }) |
135 | }) |
136 | }) |
137 | } |
138 | ) |
139 | }) |
140 | } |
141 | ) |
142 | }) |
143 | |
144 | tape('cleanup', function (t) { |
145 | alice.close() |
146 | t.end() |
147 | }) |
148 | |
149 |
Built with git-ssb-web