Move key updating and retry handling to libtextsecure
This commit is contained in:
parent
184b1ec89c
commit
a9617068a2
3 changed files with 54 additions and 31 deletions
|
@ -85,8 +85,10 @@ module.exports = function(grunt) {
|
||||||
],
|
],
|
||||||
dest: 'libtextsecure/libaxolotl_concat.js',
|
dest: 'libtextsecure/libaxolotl_concat.js',
|
||||||
},
|
},
|
||||||
|
//TODO: Move errors back down?
|
||||||
libtextsecure: {
|
libtextsecure: {
|
||||||
src: [
|
src: [
|
||||||
|
'libtextsecure/errors.js',
|
||||||
'libtextsecure/axolotl_wrapper.js',
|
'libtextsecure/axolotl_wrapper.js',
|
||||||
'libtextsecure/libaxolotl_concat.js',
|
'libtextsecure/libaxolotl_concat.js',
|
||||||
|
|
||||||
|
@ -96,7 +98,6 @@ module.exports = function(grunt) {
|
||||||
'libtextsecure/websocket.js',
|
'libtextsecure/websocket.js',
|
||||||
'libtextsecure/websocket-resources.js',
|
'libtextsecure/websocket-resources.js',
|
||||||
'libtextsecure/helpers.js',
|
'libtextsecure/helpers.js',
|
||||||
'libtextsecure/errors.js',
|
|
||||||
'libtextsecure/stringview.js',
|
'libtextsecure/stringview.js',
|
||||||
'libtextsecure/api.js',
|
'libtextsecure/api.js',
|
||||||
'libtextsecure/sendmessage.js',
|
'libtextsecure/sendmessage.js',
|
||||||
|
|
|
@ -349,25 +349,13 @@ window.textsecure.protocol = function() {
|
||||||
crypto_storage.saveSession(encodedNumber, session);
|
crypto_storage.saveSession(encodedNumber, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Rewrite this!
|
var refreshPreKeys;
|
||||||
/*var wipeIdentityAndTryMessageAgain = function(from, encodedMessage, message_id) {
|
|
||||||
// Wipe identity key!
|
|
||||||
textsecure.storage.removeEncrypted("devices" + from.split('.')[0]);
|
|
||||||
return handlePreKeyWhisperMessage(from, encodedMessage).then(
|
|
||||||
function(pushMessageContent) {
|
|
||||||
extension.trigger('message:decrypted', {
|
|
||||||
message_id : message_id,
|
|
||||||
data : pushMessageContent
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
textsecure.replay.registerFunction(wipeIdentityAndTryMessageAgain, textsecure.replay.Type.INIT_SESSION);*/
|
|
||||||
|
|
||||||
var initSessionFromPreKeyWhisperMessage = function(encodedNumber, message) {
|
var initSessionFromPreKeyWhisperMessage = function(encodedNumber, message) {
|
||||||
var preKeyPair = crypto_storage.getStoredKeyPair("preKey" + message.preKeyId);
|
var preKeyPair = crypto_storage.getStoredKeyPair("preKey" + message.preKeyId);
|
||||||
var signedPreKeyPair = crypto_storage.getStoredKeyPair("signedKey" + message.signedPreKeyId);
|
var signedPreKeyPair = crypto_storage.getStoredKeyPair("signedKey" + message.signedPreKeyId);
|
||||||
|
|
||||||
|
//TODO: Call refreshPreKeys when it looks like all our prekeys are used up?
|
||||||
|
|
||||||
var session = crypto_storage.getSessionOrIdentityKeyByBaseKey(encodedNumber, toArrayBuffer(message.baseKey));
|
var session = crypto_storage.getSessionOrIdentityKeyByBaseKey(encodedNumber, toArrayBuffer(message.baseKey));
|
||||||
var open_session = crypto_storage.getOpenSession(encodedNumber);
|
var open_session = crypto_storage.getOpenSession(encodedNumber);
|
||||||
if (signedPreKeyPair === undefined) {
|
if (signedPreKeyPair === undefined) {
|
||||||
|
@ -715,6 +703,7 @@ window.textsecure.protocol = function() {
|
||||||
crypto_storage.removeStoredKeyPair("signedKey" + (signedKeyId - 2));
|
crypto_storage.removeStoredKeyPair("signedKey" + (signedKeyId - 2));
|
||||||
|
|
||||||
return Promise.all(promises).then(function() {
|
return Promise.all(promises).then(function() {
|
||||||
|
axolotl.api.storage.put("lastPreKeyUpdate", Date.now());
|
||||||
return keys;
|
return keys;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -724,12 +713,21 @@ window.textsecure.protocol = function() {
|
||||||
return identityKeyCalculated(identityKeyPair);
|
return identityKeyCalculated(identityKeyPair);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Dont always update prekeys here
|
refreshPreKeys = function() {
|
||||||
//XXX: This is busted as fuck
|
self.generateKeys().then(function(keys) {
|
||||||
if (axolotl.api.storage.get("lastSignedKeyUpdate", Date.now()) < Date.now() - MESSAGE_LOST_THRESHOLD_MS) {
|
console.log("Pre Keys updated!");
|
||||||
new Promise(function(resolve) { resolve(self.generateKeys()); });
|
return axolotl.api.updateKeys(keys);
|
||||||
|
}).catch(function(e) {
|
||||||
|
//TODO: Notify the user somehow???
|
||||||
|
console.error(e);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.setInterval(function() {
|
||||||
|
// Note that this will not ever run until generateKeys has been called at least once
|
||||||
|
if (axolotl.api.storage.get("lastPreKeyUpdate", Date.now()) < Date.now() - MESSAGE_LOST_THRESHOLD_MS)
|
||||||
|
refreshPreKeys();
|
||||||
|
}, 60 * 1000);
|
||||||
|
|
||||||
self.prepareTempWebsocket = function() {
|
self.prepareTempWebsocket = function() {
|
||||||
var socketInfo = {};
|
var socketInfo = {};
|
||||||
|
|
|
@ -22,33 +22,41 @@
|
||||||
return textsecure.storage.removeEncrypted(key);
|
return textsecure.storage.removeEncrypted(key);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
updateKeys: function(keys) {
|
||||||
|
return textsecure.api.registerKeys(keys).catch(function(e) {
|
||||||
|
//TODO: Notify the user somehow?
|
||||||
|
console.error(e);
|
||||||
|
});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var decodeMessageContents = function(res) {
|
||||||
|
var finalMessage = textsecure.protobuf.PushMessageContent.decode(res[0]);
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
/*if ((finalMessage.flags & textsecure.protobuf.PushMessageContent.Flags.END_SESSION)
|
||||||
|
== textsecure.protobuf.PushMessageContent.Flags.END_SESSION)
|
||||||
|
textsecure.protocol.closeSession(res[1], true);*/
|
||||||
|
|
||||||
|
return finalMessage;
|
||||||
|
}
|
||||||
|
|
||||||
window.textsecure = window.textsecure || {};
|
window.textsecure = window.textsecure || {};
|
||||||
window.textsecure.protocol_wrapper = {
|
window.textsecure.protocol_wrapper = {
|
||||||
handleIncomingPushMessageProto: function(proto) {
|
handleIncomingPushMessageProto: function(proto) {
|
||||||
var decodeContents = function(res) {
|
|
||||||
var finalMessage = textsecure.protobuf.PushMessageContent.decode(res[0]);
|
|
||||||
|
|
||||||
//TODO
|
|
||||||
/*if ((finalMessage.flags & textsecure.protobuf.PushMessageContent.Flags.END_SESSION)
|
|
||||||
== textsecure.protobuf.PushMessageContent.Flags.END_SESSION)
|
|
||||||
textsecure.protocol.closeSession(res[1], true);*/
|
|
||||||
|
|
||||||
return finalMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(proto.type) {
|
switch(proto.type) {
|
||||||
case textsecure.protobuf.IncomingPushMessageSignal.Type.PLAINTEXT:
|
case textsecure.protobuf.IncomingPushMessageSignal.Type.PLAINTEXT:
|
||||||
return Promise.resolve(textsecure.protobuf.PushMessageContent.decode(proto.message));
|
return Promise.resolve(textsecure.protobuf.PushMessageContent.decode(proto.message));
|
||||||
case textsecure.protobuf.IncomingPushMessageSignal.Type.CIPHERTEXT:
|
case textsecure.protobuf.IncomingPushMessageSignal.Type.CIPHERTEXT:
|
||||||
var from = proto.source + "." + (proto.sourceDevice == null ? 0 : proto.sourceDevice);
|
var from = proto.source + "." + (proto.sourceDevice == null ? 0 : proto.sourceDevice);
|
||||||
return textsecure.protocol.decryptWhisperMessage(from, getString(proto.message)).then(decodeContents);
|
return textsecure.protocol.decryptWhisperMessage(from, getString(proto.message)).then(decodeMessageContents);
|
||||||
case textsecure.protobuf.IncomingPushMessageSignal.Type.PREKEY_BUNDLE:
|
case textsecure.protobuf.IncomingPushMessageSignal.Type.PREKEY_BUNDLE:
|
||||||
if (proto.message.readUint8() != ((3 << 4) | 3))
|
if (proto.message.readUint8() != ((3 << 4) | 3))
|
||||||
throw new Error("Bad version byte");
|
throw new Error("Bad version byte");
|
||||||
var from = proto.source + "." + (proto.sourceDevice == null ? 0 : proto.sourceDevice);
|
var from = proto.source + "." + (proto.sourceDevice == null ? 0 : proto.sourceDevice);
|
||||||
return textsecure.protocol.handlePreKeyWhisperMessage(from, getString(proto.message)).then(decodeContents);
|
return textsecure.protocol.handlePreKeyWhisperMessage(from, getString(proto.message)).then(decodeMessageContents);
|
||||||
case textsecure.protobuf.IncomingPushMessageSignal.Type.RECEIPT:
|
case textsecure.protobuf.IncomingPushMessageSignal.Type.RECEIPT:
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
case textsecure.protobuf.IncomingPushMessageSignal.Type.PREKEY_BUNDLE_DEVICE_CONTROL:
|
case textsecure.protobuf.IncomingPushMessageSignal.Type.PREKEY_BUNDLE_DEVICE_CONTROL:
|
||||||
|
@ -68,4 +76,20 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var wipeIdentityAndTryMessageAgain = function(from, encodedMessage, message_id) {
|
||||||
|
// Wipe identity key!
|
||||||
|
//TODO: Encapsuate with the rest of textsecure.storage.devices
|
||||||
|
textsecure.storage.removeEncrypted("devices" + from.split('.')[0]);
|
||||||
|
//TODO: Probably breaks with a devicecontrol message
|
||||||
|
return textsecure.protocol.handlePreKeyWhisperMessage(from, encodedMessage).then(decodeMessageContents).then(
|
||||||
|
function(pushMessageContent) {
|
||||||
|
extension.trigger('message:decrypted', {
|
||||||
|
message_id : message_id,
|
||||||
|
data : pushMessageContent
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
textsecure.replay.registerFunction(wipeIdentityAndTryMessageAgain, textsecure.replay.Type.INIT_SESSION);
|
||||||
})();
|
})();
|
||||||
|
|
Loading…
Reference in a new issue