git ssb

1+

Dominic / ssb-private-groups



Tree: 6c83ee92da37bbfea7f2b10e9bcca736b1447248

Files: 6c83ee92da37bbfea7f2b10e9bcca736b1447248 / test / index.js

3761 bytesRaw
1var chloride = require('chloride')
2var tape = require('tape')
3var group_box = require('group-box')
4var u = require('../util')
5var ssbKeys = require('ssb-keys')
6var Scuttlebot = require('ssb-server')
7 .use(require('../'))
8
9function hash (s) {
10 return chloride.crypto_hash_sha256(Buffer.from(s, 'utf8'))
11}
12
13var alice = Scuttlebot({
14 temp: true,
15 keys: ssbKeys.generate(null, hash('alice_secret1'))
16})
17
18var bob = alice.createFeed(ssbKeys.generate(null, hash('bob_secret1')))
19
20function generate (seed) {
21 var keys = chloride.crypto_box_seed_keypair(seed)
22 return {
23 public: keys.publicKey.toString('base64')+'.curve25519',
24 private: keys.secretKey.toString('base64')
25 }
26}
27
28function toBuffer(s) {
29 return Buffer.isBuffer(s) ? s : Buffer.from(s, 'base64')
30}
31
32function scalarmult (pk,sk) {
33 return chloride.crypto_scalarmult(toBuffer(pk), toBuffer(sk))
34}
35var alice_keys = generate(hash('alice_secret2'))
36var bob_keys = generate(hash('bob_secret2.1'))
37var bob_keys2 = generate(hash('bob_secret2.2'))
38
39tape('create a private-msg-key', function (t) {
40 //normally alice would publish a 'private-msg-key' message
41 //to advertise this key, but in this test bob is constructing
42 //messages manually, so it's not needed.
43 //in the future, have a way to call publish and look at the recipients
44 //and then choose the keys.
45 alice.privateGroups.addCurvePair(alice_keys, function (err) {
46 if(err) throw err
47
48 //bob doesn't call addCurvePair because bob is remote.
49 //(we are just adding his feed directly so we don't
50 // need to bother with replication)
51
52 bob.publish({
53 type: 'private-msg-key',
54 key: bob_keys.public
55 }, function (err, data) {
56 if(err) throw err
57 t.ok(data.key)
58
59 var content = { type: 'private', text: 'hello, alice' }
60 var ptxt = Buffer.from(JSON.stringify(content))
61 var nonce = u.id2Buffer(data.key)
62 var keys = [bob_keys, alice_keys].map(function (key) {
63 return scalarmult(bob_keys.private, key.public)
64 })
65 var ctxt = group_box.box(ptxt, nonce, keys)
66 var _key = group_box.unboxKey(ctxt, nonce, keys, 8)
67 t.ok(_key, 'message can be decrypted')
68 bob.publish(
69 ctxt.toString('base64')+'.box2',
70 function (err, data) {
71 if(err) throw err
72 t.ok(data)
73 alice.get({id: data.key, private: true}, function (err, msg) {
74 if(err) throw err
75 t.deepEqual(msg.content, content)
76 t.end()
77 })
78 }
79 )
80 })
81 })
82})
83
84tape('bob switches keys', function (t) {
85
86 //bob doesn't call addCurvePair because bob is remote.
87 //(we are just adding his feed directly so we don't
88 // need to bother with replication)
89 bob.publish({
90 type: 'private-msg-key',
91 key: bob_keys2.public
92 }, function (err, data) {
93 if(err) throw err
94 t.ok(data.key)
95
96 var content = { type: 'private', text: 'hello again, alice!' }
97 var ptxt = Buffer.from(JSON.stringify(content))
98 var nonce = u.id2Buffer(data.key)
99 var keys = [bob_keys2, alice_keys].map(function (key) {
100 return scalarmult(bob_keys2.private, key.public)
101 })
102 var ctxt = group_box.box(ptxt, nonce, keys)
103 var _key = group_box.unboxKey(ctxt, nonce, keys, 8)
104 t.ok(_key, 'message can be decrypted')
105 bob.publish(
106 ctxt.toString('base64')+'.box2',
107 function (err, data) {
108 if(err) throw err
109 t.ok(data)
110 alice.get({id: data.key, private: true}, function (err, msg) {
111 if(err) throw err
112 console.log(msg)
113 t.deepEqual(msg.content, content)
114 t.end()
115 })
116 }
117 )
118 })
119})
120
121//test that alice can decrypt messages after bob has switched
122//keys again.
123
124tape('cleanup', function (t) {
125 alice.close()
126 t.end()
127})
128
129

Built with git-ssb-web