Split out identity key storage from session storage

This commit is contained in:
Matt Corallo 2015-01-20 22:14:44 -10:00 committed by lilia
parent 298c8624b2
commit 1bef1ce5d3
5 changed files with 51 additions and 8 deletions

View file

@ -113,6 +113,16 @@ window.axolotl.protocol = function() {
openSessionRemaining = true; openSessionRemaining = true;
if (!openSessionRemaining) // Used as a flag to get new pre keys for the next session if (!openSessionRemaining) // Used as a flag to get new pre keys for the next session
record.registrationId = null; record.registrationId = null;
else if (record.registrationId === null && registrationId !== undefined)
record.registrationId = registrationId;
else if (record.registrationId === null)
throw new Error("Had open sessions on a record that had no registrationId set");
var identityKey = axolotl.api.storage.identityKeys.get(encodedNumber);
if (identityKey === undefined)
axolotl.api.storage.identityKeys.put(encodedNumber, record.identityKey);
else if (getString(identityKey) !== getString(record.identityKey))
throw new Error("Tried to change identity key at save time");
axolotl.api.storage.sessions.put(encodedNumber, record); axolotl.api.storage.sessions.put(encodedNumber, record);
} }
@ -160,8 +170,12 @@ window.axolotl.protocol = function() {
crypto_storage.getSessionOrIdentityKeyByBaseKey = function(encodedNumber, baseKey) { crypto_storage.getSessionOrIdentityKeyByBaseKey = function(encodedNumber, baseKey) {
var record = axolotl.api.storage.sessions.get(encodedNumber); var record = axolotl.api.storage.sessions.get(encodedNumber);
if (record === undefined) if (record === undefined) {
return undefined; var identityKey = axolotl.api.storage.identityKeys.get(encodedNumber);
if (identityKey === undefined)
return undefined;
return { indexInfo: { remoteIdentityKey: identityKey } };
}
var sessions = record._sessions; var sessions = record._sessions;
var preferredSession = record._sessions[getString(baseKey)]; var preferredSession = record._sessions[getString(baseKey)];

View file

@ -1,6 +1,7 @@
'use strict'; 'use strict';
var testSessionMap = {}; var testSessionMap = {};
var testIdentityKeysMap = {};
;(function() { ;(function() {
window.axolotl = window.axolotl || {}; window.axolotl = window.axolotl || {};
@ -24,6 +25,15 @@ var testSessionMap = {};
localStorage.removeItem(key); localStorage.removeItem(key);
}, },
identityKeys: {
get: function(identifier) {
return testIdentityKeysMap[identifier];
},
put: function(identifier, identityKey) {
testIdentityKeysMap[identifier] = identityKey;
},
},
sessions: { sessions: {
get: function(identifier) { get: function(identifier) {
return testSessionMap[identifier]; return testSessionMap[identifier];

View file

@ -224,6 +224,7 @@ describe('Protocol', function() {
it(axolotlTestVectors[i].name, function(done) { it(axolotlTestVectors[i].name, function(done) {
localStorage.clear(); localStorage.clear();
testSessionMap = {}; testSessionMap = {};
testIdentityKeysMap = {};
return runAxolotlTest(axolotlTestVectors[i].vectors).then(function(res) { return runAxolotlTest(axolotlTestVectors[i].vectors).then(function(res) {
assert(res); assert(res);
}).then(done).catch(done); }).then(done).catch(done);

View file

@ -19,17 +19,22 @@
return textsecure.storage.removeEncrypted(key); return textsecure.storage.removeEncrypted(key);
}, },
identityKeys: {
get: function(identifier) {
return textsecure.storage.devices.getIdentityKeyForNumber(textsecure.utils.unencodeNumber(identifier)[0]);
},
put: function(identifier, identityKey) {
return textsecure.storage.devices.checkSaveIdentityKeyForNumber(textsecure.utils.unencodeNumber(identifier)[0], identityKey);
},
},
sessions: { sessions: {
get: function(identifier) { get: function(identifier) {
var device = textsecure.storage.devices.getDeviceObject(identifier, true); var device = textsecure.storage.devices.getDeviceObject(identifier, true);
if (device === undefined) if (device === undefined || device.sessions === undefined)
return undefined; return undefined;
var record = new axolotl.sessions.RecipientRecord(); var record = new axolotl.sessions.RecipientRecord();
if (device.sessions !== undefined) record.deserialize(device.sessions);
record.deserialize(device.sessions);
else
// TODO: (even for numbers, not devices) We MUST return an identityKey if we have one available
record.identityKey = device.identityKey;
if (getString(device.identityKey) !== getString(record.identityKey)) if (getString(device.identityKey) !== getString(record.identityKey))
throw new Error("Got mismatched identity key on sessions load"); throw new Error("Got mismatched identity key on sessions load");
return record; return record;

View file

@ -49,6 +49,19 @@
return map === undefined ? [] : map.devices; return map === undefined ? [] : map.devices;
}, },
getIdentityKeyForNumber: function(number) {
var map = textsecure.storage.getEncrypted("devices" + number);
return map === undefined ? undefined : map.identityKey;
},
checkSaveIdentityKeyForNumber: function(number, identityKey) {
var map = textsecure.storage.getEncrypted("devices" + number);
if (map === undefined)
textsecure.storage.putEncrypted("devices" + number, { devices: [], identityKey: identityKey});
else if (getString(map.identityKey) !== getString(identityKey))
throw new Error("Attempted to overwrite a different identity key");
},
getDeviceObject: function(encodedNumber, returnIdentityKey) { getDeviceObject: function(encodedNumber, returnIdentityKey) {
var number = textsecure.utils.unencodeNumber(encodedNumber)[0]; var number = textsecure.utils.unencodeNumber(encodedNumber)[0];
var devices = textsecure.storage.devices.getDeviceObjectsForNumber(number); var devices = textsecure.storage.devices.getDeviceObjectsForNumber(number);