Skip to content

Commit f062b63

Browse files
committed
Return registration id and identity key when decrypt PreKeyWhisperMessage
This information is part of the PreKeyWhisperMessage but is required by a TextSecure implementation.
1 parent 0b2c6ed commit f062b63

File tree

6 files changed

+113
-48
lines changed

6 files changed

+113
-48
lines changed

bower.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "axolotl",
33
"main": "dist/axolotl.js",
4-
"version": "1.2.2",
4+
"version": "1.3.0",
55
"authors": [
66
"Joe Bandenburg <joe@bandenburg.com>"
77
],

dist/axolotl.js

Lines changed: 78 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@
146146
this.generateIdentityKeyPair = function () {
147147
return wrappedCrypto.generateKeyPair();
148148
};
149-
this.generateRegistrationId = co.wrap($traceurRuntime.initGeneratorFunction(function $__7(extendedRange) {
149+
this.generateRegistrationId = co.wrap($traceurRuntime.initGeneratorFunction(function $__9(extendedRange) {
150150
var upperLimit, bytes, number;
151151
return $traceurRuntime.createGeneratorInstance(function ($ctx) {
152152
while (true)
@@ -173,10 +173,10 @@
173173
default:
174174
return $ctx.end();
175175
}
176-
}, $__7, this);
176+
}, $__9, this);
177177
}));
178-
this.generatePreKeys = co.wrap($traceurRuntime.initGeneratorFunction(function $__8(start, count) {
179-
var results, i, $__9, $__10, $__11, $__12, $__13, $__14;
178+
this.generatePreKeys = co.wrap($traceurRuntime.initGeneratorFunction(function $__10(start, count) {
179+
var results, i, $__11, $__12, $__13, $__14, $__15, $__16;
180180
return $traceurRuntime.createGeneratorInstance(function ($ctx) {
181181
while (true)
182182
switch ($ctx.state) {
@@ -197,24 +197,24 @@
197197
$ctx.state = 11;
198198
break;
199199
case 5:
200-
$__9 = results.push;
201-
$__10 = wrappedCrypto.generateKeyPair;
202-
$__11 = $__10.call(wrappedCrypto);
200+
$__11 = results.push;
201+
$__12 = wrappedCrypto.generateKeyPair;
202+
$__13 = $__12.call(wrappedCrypto);
203203
$ctx.state = 6;
204204
break;
205205
case 6:
206206
$ctx.state = 2;
207-
return $__11;
207+
return $__13;
208208
case 2:
209-
$__12 = $ctx.sent;
209+
$__14 = $ctx.sent;
210210
$ctx.state = 4;
211211
break;
212212
case 4:
213-
$__13 = {
213+
$__15 = {
214214
id: (start + i) % 16777214 + 1,
215-
keyPair: $__12
215+
keyPair: $__14
216216
};
217-
$__14 = $__9.call(results, $__13);
217+
$__16 = $__11.call(results, $__15);
218218
$ctx.state = 8;
219219
break;
220220
case 9:
@@ -224,42 +224,42 @@
224224
default:
225225
return $ctx.end();
226226
}
227-
}, $__8, this);
227+
}, $__10, this);
228228
}));
229-
this.generateLastResortPreKey = co.wrap($traceurRuntime.initGeneratorFunction(function $__15() {
230-
var $__16, $__17, $__18, $__19;
229+
this.generateLastResortPreKey = co.wrap($traceurRuntime.initGeneratorFunction(function $__17() {
230+
var $__18, $__19, $__20, $__21;
231231
return $traceurRuntime.createGeneratorInstance(function ($ctx) {
232232
while (true)
233233
switch ($ctx.state) {
234234
case 0:
235-
$__16 = wrappedCrypto.generateKeyPair;
236-
$__17 = $__16.call(wrappedCrypto);
235+
$__18 = wrappedCrypto.generateKeyPair;
236+
$__19 = $__18.call(wrappedCrypto);
237237
$ctx.state = 6;
238238
break;
239239
case 6:
240240
$ctx.state = 2;
241-
return $__17;
241+
return $__19;
242242
case 2:
243-
$__18 = $ctx.sent;
243+
$__20 = $ctx.sent;
244244
$ctx.state = 4;
245245
break;
246246
case 4:
247-
$__19 = {
247+
$__21 = {
248248
id: 16777215,
249-
keyPair: $__18
249+
keyPair: $__20
250250
};
251251
$ctx.state = 8;
252252
break;
253253
case 8:
254-
$ctx.returnValue = $__19;
254+
$ctx.returnValue = $__21;
255255
$ctx.state = -2;
256256
break;
257257
default:
258258
return $ctx.end();
259259
}
260-
}, $__15, this);
260+
}, $__17, this);
261261
}));
262-
this.generateSignedPreKey = co.wrap($traceurRuntime.initGeneratorFunction(function $__20(identityKeyPair, signedPreKeyId) {
262+
this.generateSignedPreKey = co.wrap($traceurRuntime.initGeneratorFunction(function $__22(identityKeyPair, signedPreKeyId) {
263263
var keyPair, signature;
264264
return $traceurRuntime.createGeneratorInstance(function ($ctx) {
265265
while (true)
@@ -289,43 +289,71 @@
289289
default:
290290
return $ctx.end();
291291
}
292-
}, $__20, this);
292+
}, $__22, this);
293293
}));
294294
this.createSessionFromPreKeyBundle = sessionFactory.createSessionFromPreKeyBundle;
295295
this.encryptMessage = sessionCipher.encryptMessage;
296296
this.decryptWhisperMessage = sessionCipher.decryptWhisperMessage;
297-
this.decryptPreKeyWhisperMessage = co.wrap($traceurRuntime.initGeneratorFunction(function $__21(session, preKeyWhisperMessageBytes) {
298-
var $__22, $__23, $__24;
297+
this.decryptPreKeyWhisperMessage = co.wrap($traceurRuntime.initGeneratorFunction(function $__23(session, preKeyWhisperMessageBytes) {
298+
var $__7, newSession, identityKey, registrationId, $__8, finalSession, message, $__24, $__25, $__26, $__27, $__28, $__29, $__30, $__31, $__32, $__33, $__34;
299299
return $traceurRuntime.createGeneratorInstance(function ($ctx) {
300300
while (true)
301301
switch ($ctx.state) {
302302
case 0:
303+
$__24 = sessionFactory.createSessionFromPreKeyWhisperMessage;
304+
$__25 = $__24.call(sessionFactory, session, preKeyWhisperMessageBytes);
305+
$ctx.state = 6;
306+
break;
307+
case 6:
303308
$ctx.state = 2;
304-
return sessionFactory.createSessionFromPreKeyWhisperMessage(session, preKeyWhisperMessageBytes);
309+
return $__25;
305310
case 2:
306-
session = $ctx.sent;
311+
$__26 = $ctx.sent;
307312
$ctx.state = 4;
308313
break;
309314
case 4:
310-
$__22 = sessionCipher.decryptPreKeyWhisperMessage;
311-
$__23 = $__22.call(sessionCipher, session, preKeyWhisperMessageBytes);
312-
$ctx.state = 10;
313-
break;
314-
case 10:
315-
$ctx.state = 6;
316-
return $__23;
317-
case 6:
318-
$__24 = $ctx.sent;
315+
$__7 = $__26;
316+
$__27 = $__7.session;
317+
newSession = $__27;
318+
$__28 = $__7.identityKey;
319+
identityKey = $__28;
320+
$__29 = $__7.registrationId;
321+
registrationId = $__29;
319322
$ctx.state = 8;
320323
break;
321324
case 8:
322-
$ctx.returnValue = $__24;
325+
$__30 = sessionCipher.decryptPreKeyWhisperMessage;
326+
$__31 = $__30.call(sessionCipher, newSession, preKeyWhisperMessageBytes);
327+
$ctx.state = 14;
328+
break;
329+
case 14:
330+
$ctx.state = 10;
331+
return $__31;
332+
case 10:
333+
$__32 = $ctx.sent;
334+
$ctx.state = 12;
335+
break;
336+
case 12:
337+
$__8 = $__32;
338+
$__33 = $__8.session;
339+
finalSession = $__33;
340+
$__34 = $__8.message;
341+
message = $__34;
342+
$ctx.state = 16;
343+
break;
344+
case 16:
345+
$ctx.returnValue = {
346+
message: message,
347+
session: finalSession,
348+
identityKey: identityKey,
349+
registrationId: registrationId
350+
};
323351
$ctx.state = -2;
324352
break;
325353
default:
326354
return $ctx.end();
327355
}
328-
}, $__21, this);
356+
}, $__23, this);
329357
}));
330358
Object.freeze(self);
331359
}
@@ -1698,7 +1726,11 @@
16981726
$ctx.state = cachedSessionState.theirBaseKey && ArrayBufferUtils.areEqual(cachedSessionState.theirBaseKey, message.baseKey) ? 1 : 2;
16991727
break;
17001728
case 1:
1701-
$ctx.returnValue = session;
1729+
$ctx.returnValue = {
1730+
session: session,
1731+
identityKey: message.identityKey,
1732+
registrationId: message.registrationId
1733+
};
17021734
$ctx.state = -2;
17031735
break;
17041736
case 6:
@@ -1761,7 +1793,11 @@
17611793
$ctx.state = 35;
17621794
break;
17631795
case 35:
1764-
$ctx.returnValue = clonedSession;
1796+
$ctx.returnValue = {
1797+
session: clonedSession,
1798+
identityKey: message.identityKey,
1799+
registrationId: message.registrationId
1800+
};
17651801
$ctx.state = -2;
17661802
break;
17671803
default:

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "axolotl",
3-
"version": "1.2.2",
3+
"version": "1.3.0",
44
"description": "An indepedent JavaScript implementation of Axolotl. Axolotl is a ratcheting forward secrecy protocol.",
55
"main": "dist/axolotl.js",
66
"directories": {

src/Axolotl.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,21 @@ function Axolotl(crypto, store) {
232232
* @returns {Promise.<Object, InvalidMessageException>} an object containing the decrypted message and a new session
233233
*/
234234
this.decryptPreKeyWhisperMessage = co.wrap(function*(session, preKeyWhisperMessageBytes) {
235-
session = yield sessionFactory.createSessionFromPreKeyWhisperMessage(session, preKeyWhisperMessageBytes);
236-
return yield sessionCipher.decryptPreKeyWhisperMessage(session, preKeyWhisperMessageBytes);
235+
var {
236+
session: newSession,
237+
identityKey,
238+
registrationId
239+
} = yield sessionFactory.createSessionFromPreKeyWhisperMessage(session, preKeyWhisperMessageBytes);
240+
var {
241+
session: finalSession,
242+
message
243+
} = yield sessionCipher.decryptPreKeyWhisperMessage(newSession, preKeyWhisperMessageBytes);
244+
return {
245+
message: message,
246+
session: finalSession,
247+
identityKey: identityKey,
248+
registrationId: registrationId
249+
};
237250
});
238251

239252
Object.freeze(self);

src/SessionFactory.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,11 @@ function SessionFactory(crypto, store) {
105105
for (var cachedSessionState of session.states) {
106106
if (cachedSessionState.theirBaseKey &&
107107
ArrayBufferUtils.areEqual(cachedSessionState.theirBaseKey, message.baseKey)) {
108-
return session;
108+
return {
109+
session: session,
110+
identityKey: message.identityKey,
111+
registrationId: message.registrationId
112+
};
109113
}
110114
}
111115
}
@@ -131,7 +135,11 @@ function SessionFactory(crypto, store) {
131135
sessionState.theirBaseKey = message.baseKey;
132136
var clonedSession = new Session(session);
133137
clonedSession.addState(sessionState);
134-
return clonedSession;
138+
return {
139+
session: clonedSession,
140+
identityKey: message.identityKey,
141+
registrationId: message.registrationId
142+
};
135143
});
136144

137145
// TODO: Implement

test/unit/Axolotl.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,5 +484,13 @@ describe("Axolotl", () => {
484484
yield assertSessionsCanCommunicateTwoWay();
485485
}));
486486
});
487+
it("returns the identity key and registration id when decrypting a PreKeyWhisperMessage", co.wrap(function*() {
488+
var plaintext = crypto.randomBytes(10);
489+
var aliceInitialSession = yield aliceAxolotl.createSessionFromPreKeyBundle(bobPreKeyBundle);
490+
var encryptionResult = yield aliceAxolotl.encryptMessage(aliceInitialSession, plaintext);
491+
var decryptionResult = yield bobAxolotl.decryptPreKeyWhisperMessage(null, encryptionResult.body);
492+
assert.equal(decryptionResult.registrationId, 666);
493+
assert.ok(ArrayBufferUtils.areEqual(decryptionResult.identityKey, aliceIdentityKeyPair.public));
494+
}));
487495
});
488496
});

0 commit comments

Comments
 (0)