Commit e39f1662dc45833d09248b820abe6f694160a37a
fix groups
Dominic Tarr committed on 12/29/2018, 8:32:50 AMParent: 4de96c011f2e32da25a86df102a8af549f39d44c
Files changed
index.js | changed |
package.json | changed |
util.js | changed |
index.js | ||
---|---|---|
@@ -3,9 +3,9 @@ | ||
3 | 3 … | var Reduce = require('flumeview-reduce') |
4 | 4 … | var group_box = require('group-box') |
5 | 5 … | var mkdirp = require('mkdirp') |
6 | 6 … | var u = require('./util') |
7 | -var cl = require('chloride') | |
7 … | +var ref = require('ssb-ref') | |
8 | 8 … | |
9 | 9 … | //by deriving the message key from the group id (the founding |
10 | 10 … | //message id) and the unbox key for that message, this ensures |
11 | 11 … | //someone can't decrypt the message without knowing the founding |
@@ -16,17 +16,8 @@ | ||
16 | 16 … | //and, you can verify this property from the design! you can't |
17 | 17 … | //rewrite this code so they don't know the founding message |
18 | 18 … | //and still be able to decrypt these messages. |
19 | 19 … | |
20 | -function hmac (a, b) { | |
21 | - return cl.crypto_auth(u.toBuffer(a), u.toBuffer(b)) | |
22 | -} | |
23 | - | |
24 | -function getGroupMsgKey(previous, group) { | |
25 | - //or would it be better to use generic hash (with key?) | |
26 | - return hmac(Buffer.concat([previous, group.id]), u.toBuffer(group.unbox)) | |
27 | -} | |
28 | - | |
29 | 20 … | exports.name = 'private-groups' |
30 | 21 … | |
31 | 22 … | exports.init = function (sbot, config) { |
32 | 23 … | |
@@ -103,28 +94,24 @@ | ||
103 | 94 … | } |
104 | 95 … | if(!a_key) return console.log('no author key') |
105 | 96 … | |
106 | 97 … | if(!keys_to_try) |
107 | - keys_to_try = cache[value.author] = keyState.msgKeys.map(function (curve) { | |
108 | - return cl.crypto_scalarmult( | |
109 | - Buffer.from(curve.private, 'base64'), | |
110 | - Buffer.from(a_key, 'base64') | |
111 | - ) | |
112 | - }) | |
98 … | + keys_to_try = cache[value.author] = u.scalarmultKeys(a_key, keyState.msgKeys) | |
113 | 99 … | |
114 | 100 … | //the very first message cannot be a group_box. |
115 | 101 … | if(value.previous == null) return |
116 | 102 … | var ctxt = u.ctxt2Buffer(content) |
117 | 103 … | var nonce = u.id2Buffer(value.previous) |
104 … | + console.log(content, ctxt, ctxt.length) | |
118 | 105 … | |
119 | 106 … | var key = group_box.unboxKey(ctxt, nonce, keys_to_try, 8) |
120 | 107 … | if(key) return key |
121 | 108 … | |
122 | 109 … | //should group keys be included in this plugin? |
123 | 110 … | //yes, because box2 supports both direct keys and group keys. |
124 | 111 … | var group_keys = [] |
125 | 112 … | for(var id in keyState.groupKeys) |
126 | - group_keys.push(getGroupMsgKey(nonce, keyState.groupKeys[id])) | |
113 … | + group_keys.push(u.getGroupMsgKey(nonce, keyState.groupKeys[id])) | |
127 | 114 … | |
128 | 115 … | //note: if we only allow groups in the first 4 slots |
129 | 116 … | //that means better sort them before any individuals |
130 | 117 … | key = group_box.unboxKey( //groups we are in |
@@ -145,11 +132,14 @@ | ||
145 | 132 … | |
146 | 133 … | return { |
147 | 134 … | get: remoteKeys.get, |
148 | 135 … | addGroupKey: function (group, cb) { |
136 … | + console.log(group, u.isUnboxKey(group.unbox)) | |
137 … | + if(!ref.isMsg(group.id)) return cb(new Error('id must be a message id')) | |
138 … | + if(!u.isUnboxKey(group.unbox)) return cb(new Error('id must be a 32 byte base64 value')) | |
149 | 139 … | af.get(function () { |
150 | - keyState.groupKeys[hmac(group.id, group.unbox)] = group | |
151 | - af.set(keys, cb) | |
140 … | + keyState.groupKeys[u.hmac(u.id2Buffer(group.id), Buffer.from(group.unbox, 'base64'))] = group | |
141 … | + af.set(keyState, cb) | |
152 | 142 … | }) |
153 | 143 … | }, |
154 | 144 … | addCurvePair: function (curve_keys, cb) { |
155 | 145 … | onReady(function () { |
@@ -176,4 +166,5 @@ | ||
176 | 166 … | } |
177 | 167 … | } |
178 | 168 … | } |
179 | 169 … | |
170 … | + |
package.json | ||
---|---|---|
@@ -7,9 +7,11 @@ | ||
7 | 7 … | "type": "git", |
8 | 8 … | "url": "git://github.com/dominictarr/ssb-private-groups.git" |
9 | 9 … | }, |
10 | 10 … | "dependencies": { |
11 | - "atomic-file": "^1.1.5" | |
11 … | + "atomic-file": "^1.1.5", | |
12 … | + "group-box": "^0.1.0", | |
13 … | + "is-canonical-base64": "^1.1.1" | |
12 | 14 … | }, |
13 | 15 … | "devDependencies": { |
14 | 16 … | "ssb-server": "^13.4.0", |
15 | 17 … | "tape": "^4.9.1" |
util.js | ||
---|---|---|
@@ -1,5 +1,11 @@ | ||
1 … | +var cl = require('chloride') | |
1 | 2 … | |
3 … | +//var rx = require('is-canonical-base64')(null, null, 32) | |
4 … | +exports.isUnboxKey = function (s) { | |
5 … | + return s === Buffer.from(s, 'base64').toString('base64') | |
6 … | +// return rx.test(s) | |
7 … | +} | |
2 | 8 … | exports.id2Buffer = function (id) { |
3 | 9 … | return Buffer.from(id.substring(1, id.indexOf('.')), 'base64') |
4 | 10 … | } |
5 | 11 … | |
@@ -16,4 +22,29 @@ | ||
16 | 22 … | exports.ctxt2Buffer = function (ctxt) { |
17 | 23 … | return exports.isBox2(ctxt) && Buffer.from(ctxt.substring(0, ctxt.indexOf('.')), 'base64') |
18 | 24 … | } |
19 | 25 … | |
26 … | +function toBuffer(b) { | |
27 … | + return Buffer.isBuffer(b) ? b : Buffer.from(b, 'base64') | |
28 … | +} | |
29 … | + | |
30 … | +exports.hmac = function (a, b) { | |
31 … | + return cl.crypto_auth(toBuffer(a), toBuffer(b)) | |
32 … | +} | |
33 … | + | |
34 … | +exports.getGroupMsgKey = function (previous, group) { | |
35 … | + //or would it be better to use generic hash (with key?) | |
36 … | + return exports.hmac(Buffer.concat([previous, exports.id2Buffer(group.id)]), Buffer.from(group.unbox, 'base64')) | |
37 … | +} | |
38 … | + | |
39 … | +exports.scalarmultKeys = function (a_key, recps) { | |
40 … | + return recps.map(function (curve) { | |
41 … | + return cl.crypto_scalarmult( | |
42 … | + toBuffer(curve.private), | |
43 … | + toBuffer(a_key) | |
44 … | + ) | |
45 … | + }) | |
46 … | +} | |
47 … | + | |
48 … | + | |
49 … | + | |
50 … | + |
Built with git-ssb-web