signal-desktop/libtextsecure/protocol_wrapper.js
lilia 9f871db48a Update libsignal-protocol / Update prekey format
Integrates change in prekey object formatting, which now matches more
conveniently with the representation rendered by the server.

// FREEBIE
2016-05-04 00:33:05 -07:00

94 lines
3.8 KiB
JavaScript

/*
* vim: ts=4:sw=4:expandtab
*/
;(function() {
'use strict';
window.textsecure = window.textsecure || {};
window.textsecure.storage = window.textsecure.storage || {};
textsecure.storage.protocol = new SignalProtocolStore();
var protocolInstance = libsignal.protocol(textsecure.storage.protocol);
/*
* jobQueue manages multiple queues indexed by device to serialize
* session io ops on the database.
*/
var jobQueue = {};
function queueJobForNumber(number, runJob) {
var runPrevious = jobQueue[number] || Promise.resolve();
var runCurrent = jobQueue[number] = runPrevious.then(runJob, runJob);
runCurrent.then(function() {
if (jobQueue[number] === runCurrent) {
delete jobQueue[number];
}
});
return runCurrent;
}
window.textsecure = window.textsecure || {};
window.textsecure.protocol_wrapper = {
decryptWhisperMessage: function(fromAddress, blob) {
return queueJobForNumber(fromAddress, function() {
return protocolInstance.decryptWhisperMessage(fromAddress, blob.toArrayBuffer());
});
},
closeOpenSessionForDevice: function(encodedNumber) {
return queueJobForNumber(encodedNumber, function() {
return protocolInstance.closeOpenSessionForDevice(encodedNumber);
});
},
encryptMessageFor: function(deviceObject, pushMessageContent) {
return queueJobForNumber(deviceObject.encodedNumber, function() {
return protocolInstance.encryptMessageFor(deviceObject, pushMessageContent);
});
},
startWorker: function() {
protocolInstance.startWorker('/js/libsignal-protocol-worker.js');
},
stopWorker: function() {
protocolInstance.stopWorker();
},
createIdentityKeyRecvSocket: function() {
return protocolInstance.createIdentityKeyRecvSocket();
},
hasOpenSession: function(encodedNumber) {
return queueJobForNumber(encodedNumber, function() {
return protocolInstance.hasOpenSession(encodedNumber);
});
},
getRegistrationId: function(encodedNumber) {
return queueJobForNumber(encodedNumber, function() {
return protocolInstance.getRegistrationId(encodedNumber);
});
},
handlePreKeyWhisperMessage: function(from, blob) {
console.log('prekey whisper message');
blob.mark();
var version = blob.readUint8();
if ((version & 0xF) > 3 || (version >> 4) < 3) {
// min version > 3 or max version < 3
throw new Error("Incompatible version byte");
}
return queueJobForNumber(from, function() {
return protocolInstance.handlePreKeyWhisperMessage(from, blob).catch(function(e) {
if (e.message === 'Unknown identity key') {
blob.reset(); // restore the version byte.
// create an error that the UI will pick up and ask the
// user if they want to re-negotiate
throw new textsecure.IncomingIdentityKeyError(from, blob.toArrayBuffer(), e.identityKey);
}
throw e;
});
});
},
processPreKey: function(preKeyBundle) {
return queueJobForNumber(preKeyBundle.encodedNumber, function() {
var address = libsignal.SignalProtocolAddress.fromString(preKeyBundle.encodedNumber);
var builder = new libsignal.SessionBuilder(textsecure.storage.protocol, address);
return builder.processPreKey(preKeyBundle);
});
}
};
})();