MessageReceiver uses SessionCipher to retry conflicts

// FREEBIE
This commit is contained in:
lilia 2016-05-02 17:12:18 -07:00
parent 9ecfe6acb0
commit d5f4665fa4
2 changed files with 58 additions and 46 deletions

View file

@ -37038,26 +37038,7 @@ MessageReceiver.prototype.extend({
break; break;
case textsecure.protobuf.Envelope.Type.PREKEY_BUNDLE: case textsecure.protobuf.Envelope.Type.PREKEY_BUNDLE:
console.log('prekey whisper message'); console.log('prekey whisper message');
ciphertext.mark(); promise = this.decryptPreKeyWhisperMessage(ciphertext, sessionCipher, address);
var version = ciphertext.readUint8();
if ((version & 0xF) > 3 || (version >> 4) < 3) {
// min version > 3 or max version < 3
throw new Error("Incompatible version byte");
}
promise = sessionCipher.decryptPreKeyWhisperMessage(ciphertext).catch(function(e) {
if (e.message === 'Unknown identity key') {
ciphertext.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(
address.toString(),
ciphertext.toArrayBuffer(),
e.identityKey
);
}
throw e;
});
break; break;
default: default:
promise = Promise.reject(new Error("Unknown message type")); promise = Promise.reject(new Error("Unknown message type"));
@ -37070,6 +37051,28 @@ MessageReceiver.prototype.extend({
return Promise.reject(error); return Promise.reject(error);
}.bind(this)); }.bind(this));
}, },
decryptPreKeyWhisperMessage: function(ciphertext, sessionCipher, address) {
ciphertext.mark();
var version = ciphertext.readUint8();
if ((version & 0xF) > 3 || (version >> 4) < 3) {
// min version > 3 or max version < 3
throw new Error("Incompatible version byte");
}
return sessionCipher.decryptPreKeyWhisperMessage(ciphertext).catch(function(e) {
if (e.message === 'Unknown identity key') {
ciphertext.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(
address.toString(),
ciphertext.toArrayBuffer(),
e.identityKey
);
}
throw e;
});
},
handleSentMessage: function(destination, timestamp, message) { handleSentMessage: function(destination, timestamp, message) {
var p = Promise.resolve(); var p = Promise.resolve();
if ((message.flags & textsecure.protobuf.DataMessage.Flags.END_SESSION) == if ((message.flags & textsecure.protobuf.DataMessage.Flags.END_SESSION) ==
@ -37244,15 +37247,18 @@ MessageReceiver.prototype.extend({
then(updateAttachment); then(updateAttachment);
}, },
tryMessageAgain: function(from, encodedMessage) { tryMessageAgain: function(from, encodedMessage) {
var bytes = dcodeIO.ByteBuffer.wrap(encodedMessage); var ciphertext = dcodeIO.ByteBuffer.wrap(encodedMessage);
return textsecure.protocol_wrapper.handlePreKeyWhisperMessage(from, bytes).then(function(res) { var address = libsignal.SignalProtocolAddress.fromString(from);
var sessionCipher = new libsignal.SessionCipher(textsecure.storage.protocol, address);
console.log('retrying prekey whisper message');
return this.decryptPreKeyWhisperMessage(ciphertext, sessionCipher, address).then(function(res) {
var finalMessage = textsecure.protobuf.DataMessage.decode(res[0]); var finalMessage = textsecure.protobuf.DataMessage.decode(res[0]);
var p = Promise.resolve(); var p = Promise.resolve();
if ((finalMessage.flags & textsecure.protobuf.DataMessage.Flags.END_SESSION) if ((finalMessage.flags & textsecure.protobuf.DataMessage.Flags.END_SESSION)
== textsecure.protobuf.DataMessage.Flags.END_SESSION && == textsecure.protobuf.DataMessage.Flags.END_SESSION &&
finalMessage.sync !== null) { finalMessage.sync !== null) {
var number = textsecure.utils.unencodeNumber(from)[0]; var number = address.getName();
p = this.handleEndSession(number); p = this.handleEndSession(number);
} }

View file

@ -118,26 +118,7 @@ MessageReceiver.prototype.extend({
break; break;
case textsecure.protobuf.Envelope.Type.PREKEY_BUNDLE: case textsecure.protobuf.Envelope.Type.PREKEY_BUNDLE:
console.log('prekey whisper message'); console.log('prekey whisper message');
ciphertext.mark(); promise = this.decryptPreKeyWhisperMessage(ciphertext, sessionCipher, address);
var version = ciphertext.readUint8();
if ((version & 0xF) > 3 || (version >> 4) < 3) {
// min version > 3 or max version < 3
throw new Error("Incompatible version byte");
}
promise = sessionCipher.decryptPreKeyWhisperMessage(ciphertext).catch(function(e) {
if (e.message === 'Unknown identity key') {
ciphertext.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(
address.toString(),
ciphertext.toArrayBuffer(),
e.identityKey
);
}
throw e;
});
break; break;
default: default:
promise = Promise.reject(new Error("Unknown message type")); promise = Promise.reject(new Error("Unknown message type"));
@ -150,6 +131,28 @@ MessageReceiver.prototype.extend({
return Promise.reject(error); return Promise.reject(error);
}.bind(this)); }.bind(this));
}, },
decryptPreKeyWhisperMessage: function(ciphertext, sessionCipher, address) {
ciphertext.mark();
var version = ciphertext.readUint8();
if ((version & 0xF) > 3 || (version >> 4) < 3) {
// min version > 3 or max version < 3
throw new Error("Incompatible version byte");
}
return sessionCipher.decryptPreKeyWhisperMessage(ciphertext).catch(function(e) {
if (e.message === 'Unknown identity key') {
ciphertext.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(
address.toString(),
ciphertext.toArrayBuffer(),
e.identityKey
);
}
throw e;
});
},
handleSentMessage: function(destination, timestamp, message) { handleSentMessage: function(destination, timestamp, message) {
var p = Promise.resolve(); var p = Promise.resolve();
if ((message.flags & textsecure.protobuf.DataMessage.Flags.END_SESSION) == if ((message.flags & textsecure.protobuf.DataMessage.Flags.END_SESSION) ==
@ -324,15 +327,18 @@ MessageReceiver.prototype.extend({
then(updateAttachment); then(updateAttachment);
}, },
tryMessageAgain: function(from, encodedMessage) { tryMessageAgain: function(from, encodedMessage) {
var bytes = dcodeIO.ByteBuffer.wrap(encodedMessage); var ciphertext = dcodeIO.ByteBuffer.wrap(encodedMessage);
return textsecure.protocol_wrapper.handlePreKeyWhisperMessage(from, bytes).then(function(res) { var address = libsignal.SignalProtocolAddress.fromString(from);
var sessionCipher = new libsignal.SessionCipher(textsecure.storage.protocol, address);
console.log('retrying prekey whisper message');
return this.decryptPreKeyWhisperMessage(ciphertext, sessionCipher, address).then(function(res) {
var finalMessage = textsecure.protobuf.DataMessage.decode(res[0]); var finalMessage = textsecure.protobuf.DataMessage.decode(res[0]);
var p = Promise.resolve(); var p = Promise.resolve();
if ((finalMessage.flags & textsecure.protobuf.DataMessage.Flags.END_SESSION) if ((finalMessage.flags & textsecure.protobuf.DataMessage.Flags.END_SESSION)
== textsecure.protobuf.DataMessage.Flags.END_SESSION && == textsecure.protobuf.DataMessage.Flags.END_SESSION &&
finalMessage.sync !== null) { finalMessage.sync !== null) {
var number = textsecure.utils.unencodeNumber(from)[0]; var number = address.getName();
p = this.handleEndSession(number); p = this.handleEndSession(number);
} }