Refactor textsecure.protos -> textsecure.protobuf
DRY up protobuf declarations and move to a slightly briefer naming convention. Also dropped some ArrayBuffer -> string conversions as ProtoBuf.js handles ArrayBuffers just fine, and in fact, more efficiently than strings. Finally, dropped the btoa() wrappers, because that incurs an extra string -> string conversion before the protobuf's internal string -> array buffer conversion. In lieu of btoa, we can simply pass in the optional string encoding argument to the protobuf's decode method, which in these cases should be 'binary'. Related: #17
This commit is contained in:
parent
03cc667e48
commit
1023ea1732
9 changed files with 79 additions and 96 deletions
|
@ -27,6 +27,7 @@
|
||||||
<script type="text/javascript" src="js-deps/backbone.localStorage.js"></script>
|
<script type="text/javascript" src="js-deps/backbone.localStorage.js"></script>
|
||||||
<script type="text/javascript" src="js-deps/libphonenumber_api-compiled.js"></script>
|
<script type="text/javascript" src="js-deps/libphonenumber_api-compiled.js"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="js/protobufs.js"></script>
|
||||||
<script type="text/javascript" src="js/helpers.js"></script>
|
<script type="text/javascript" src="js/helpers.js"></script>
|
||||||
<script type="text/javascript" src="js/libphonenumber-util.js"></script>
|
<script type="text/javascript" src="js/libphonenumber-util.js"></script>
|
||||||
<script type="text/javascript" src="js/webcrypto.js"></script>
|
<script type="text/javascript" src="js/webcrypto.js"></script>
|
||||||
|
|
|
@ -129,6 +129,7 @@
|
||||||
<script type="text/javascript" src="js-deps/mustache.js"></script>
|
<script type="text/javascript" src="js-deps/mustache.js"></script>
|
||||||
<script type="text/javascript" src="js-deps/libphonenumber_api-compiled.js"></script>
|
<script type="text/javascript" src="js-deps/libphonenumber_api-compiled.js"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="js/protobufs.js"></script>
|
||||||
<script type="text/javascript" src="js/helpers.js"></script>
|
<script type="text/javascript" src="js/helpers.js"></script>
|
||||||
<script type="text/javascript" src="js/libphonenumber-util.js"></script>
|
<script type="text/javascript" src="js/libphonenumber-util.js"></script>
|
||||||
<script type="text/javascript" src="js/webcrypto.js"></script>
|
<script type="text/javascript" src="js/webcrypto.js"></script>
|
||||||
|
|
26
js/crypto.js
26
js/crypto.js
|
@ -536,7 +536,7 @@ window.textsecure.crypto = function() {
|
||||||
var initSessionFromPreKeyWhisperMessage;
|
var initSessionFromPreKeyWhisperMessage;
|
||||||
var decryptWhisperMessage;
|
var decryptWhisperMessage;
|
||||||
var handlePreKeyWhisperMessage = function(from, encodedMessage) {
|
var handlePreKeyWhisperMessage = function(from, encodedMessage) {
|
||||||
var preKeyProto = textsecure.protos.decodePreKeyWhisperMessageProtobuf(encodedMessage);
|
var preKeyProto = textsecure.protobuf.PreKeyWhisperMessage.decode(encodedMessage, 'binary');
|
||||||
return initSessionFromPreKeyWhisperMessage(from, preKeyProto).then(function(sessions) {
|
return initSessionFromPreKeyWhisperMessage(from, preKeyProto).then(function(sessions) {
|
||||||
return decryptWhisperMessage(from, getString(preKeyProto.message), sessions[0], preKeyProto.registrationId).then(function(result) {
|
return decryptWhisperMessage(from, getString(preKeyProto.message), sessions[0], preKeyProto.registrationId).then(function(result) {
|
||||||
if (sessions[1] !== undefined)
|
if (sessions[1] !== undefined)
|
||||||
|
@ -662,7 +662,7 @@ window.textsecure.crypto = function() {
|
||||||
var messageProto = messageBytes.substring(1, messageBytes.length - 8);
|
var messageProto = messageBytes.substring(1, messageBytes.length - 8);
|
||||||
var mac = messageBytes.substring(messageBytes.length - 8, messageBytes.length);
|
var mac = messageBytes.substring(messageBytes.length - 8, messageBytes.length);
|
||||||
|
|
||||||
var message = textsecure.protos.decodeWhisperMessageProtobuf(messageProto);
|
var message = textsecure.protobuf.WhisperMessage.decode(messageProto, 'binary');
|
||||||
var remoteEphemeralKey = toArrayBuffer(message.ephemeralKey);
|
var remoteEphemeralKey = toArrayBuffer(message.ephemeralKey);
|
||||||
|
|
||||||
if (session === undefined) {
|
if (session === undefined) {
|
||||||
|
@ -704,10 +704,10 @@ window.textsecure.crypto = function() {
|
||||||
|
|
||||||
delete session['pendingPreKey'];
|
delete session['pendingPreKey'];
|
||||||
|
|
||||||
var finalMessage = textsecure.protos.decodePushMessageContentProtobuf(getString(plaintext));
|
var finalMessage = textsecure.protobuf.PushMessageContent.decode(plaintext);
|
||||||
|
|
||||||
if ((finalMessage.flags & textsecure.protos.PushMessageContentProtobuf.Flags.END_SESSION)
|
if ((finalMessage.flags & textsecure.protobuf.PushMessageContent.Flags.END_SESSION)
|
||||||
== textsecure.protos.PushMessageContentProtobuf.Flags.END_SESSION)
|
== textsecure.protobuf.PushMessageContent.Flags.END_SESSION)
|
||||||
closeSession(session, true);
|
closeSession(session, true);
|
||||||
|
|
||||||
removeOldChains(session);
|
removeOldChains(session);
|
||||||
|
@ -778,17 +778,17 @@ window.textsecure.crypto = function() {
|
||||||
|
|
||||||
self.handleIncomingPushMessageProto = function(proto) {
|
self.handleIncomingPushMessageProto = function(proto) {
|
||||||
switch(proto.type) {
|
switch(proto.type) {
|
||||||
case textsecure.protos.IncomingPushMessageProtobuf.Type.PLAINTEXT:
|
case textsecure.protobuf.IncomingPushMessageSignal.Type.PLAINTEXT:
|
||||||
return Promise.resolve(textsecure.protos.decodePushMessageContentProtobuf(getString(proto.message)));
|
return Promise.resolve(textsecure.protobuf.PushMessageContent.decode(proto.message));
|
||||||
case textsecure.protos.IncomingPushMessageProtobuf.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 decryptWhisperMessage(from, getString(proto.message));
|
return decryptWhisperMessage(from, getString(proto.message));
|
||||||
case textsecure.protos.IncomingPushMessageProtobuf.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 handlePreKeyWhisperMessage(from, getString(proto.message));
|
return handlePreKeyWhisperMessage(from, getString(proto.message));
|
||||||
case textsecure.protos.IncomingPushMessageProtobuf.Type.RECEIPT:
|
case textsecure.protobuf.IncomingPushMessageSignal.Type.RECEIPT:
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
default:
|
default:
|
||||||
return new Promise(function(resolve, reject) { reject(new Error("Unknown message type")); });
|
return new Promise(function(resolve, reject) { reject(new Error("Unknown message type")); });
|
||||||
|
@ -800,7 +800,7 @@ window.textsecure.crypto = function() {
|
||||||
var session = crypto_storage.getOpenSession(deviceObject.encodedNumber);
|
var session = crypto_storage.getOpenSession(deviceObject.encodedNumber);
|
||||||
|
|
||||||
var doEncryptPushMessageContent = function() {
|
var doEncryptPushMessageContent = function() {
|
||||||
var msg = new textsecure.protos.WhisperMessageProtobuf();
|
var msg = new textsecure.protobuf.WhisperMessage();
|
||||||
var plaintext = toArrayBuffer(pushMessageContent.encode());
|
var plaintext = toArrayBuffer(pushMessageContent.encode());
|
||||||
|
|
||||||
var paddedPlaintext = new Uint8Array(Math.ceil((plaintext.byteLength + 1) / 160.0) * 160);
|
var paddedPlaintext = new Uint8Array(Math.ceil((plaintext.byteLength + 1) / 160.0) * 160);
|
||||||
|
@ -850,7 +850,7 @@ window.textsecure.crypto = function() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var preKeyMsg = new textsecure.protos.PreKeyWhisperMessageProtobuf();
|
var preKeyMsg = new textsecure.protobuf.PreKeyWhisperMessage();
|
||||||
preKeyMsg.identityKey = toArrayBuffer(crypto_storage.getIdentityKey().pubKey);
|
preKeyMsg.identityKey = toArrayBuffer(crypto_storage.getIdentityKey().pubKey);
|
||||||
preKeyMsg.registrationId = textsecure.storage.getUnencrypted("registrationId");
|
preKeyMsg.registrationId = textsecure.storage.getUnencrypted("registrationId");
|
||||||
|
|
||||||
|
@ -957,7 +957,7 @@ window.textsecure.crypto = function() {
|
||||||
|
|
||||||
return verifyMAC(ivAndCiphertext, ecRes[1], mac).then(function() {
|
return verifyMAC(ivAndCiphertext, ecRes[1], mac).then(function() {
|
||||||
window.crypto.subtle.decrypt({name: "AES-CBC", iv: iv}, ecRes[0], ciphertext).then(function(plaintext) {
|
window.crypto.subtle.decrypt({name: "AES-CBC", iv: iv}, ecRes[0], ciphertext).then(function(plaintext) {
|
||||||
var identityKeyMsg = textsecure.protos.decodeIdentityKeyProtobuf(getString(plaintext));
|
var identityKeyMsg = textsecure.protobuf.IdentityKey.decode(plaintext);
|
||||||
|
|
||||||
privToPub(toArrayBuffer(identityKeyMsg.identityKey)).then(function(identityKeyPair) {
|
privToPub(toArrayBuffer(identityKeyMsg.identityKey)).then(function(identityKeyPair) {
|
||||||
crypto_storage.putKeyPair("identityKey", identityKeyPair);
|
crypto_storage.putKeyPair("identityKey", identityKeyPair);
|
||||||
|
|
|
@ -167,49 +167,6 @@ function base64ToArrayBuffer(string) {
|
||||||
return base64DecToArr(string);
|
return base64DecToArr(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Protobuf decoding
|
|
||||||
//TODO: throw on missing fields everywhere
|
|
||||||
window.textsecure.protos = function() {
|
|
||||||
var self = {};
|
|
||||||
|
|
||||||
self.IncomingPushMessageProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/IncomingPushMessageSignal.proto").build("textsecure.IncomingPushMessageSignal");
|
|
||||||
self.decodeIncomingPushMessageProtobuf = function(string) {
|
|
||||||
return self.IncomingPushMessageProtobuf.decode(btoa(string));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.PushMessageContentProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/IncomingPushMessageSignal.proto").build("textsecure.PushMessageContent");
|
|
||||||
self.decodePushMessageContentProtobuf = function(string) {
|
|
||||||
return self.PushMessageContentProtobuf.decode(btoa(string));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.WhisperMessageProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/WhisperTextProtocol.proto").build("textsecure.WhisperMessage");
|
|
||||||
self.decodeWhisperMessageProtobuf = function(string) {
|
|
||||||
return self.WhisperMessageProtobuf.decode(btoa(string));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.PreKeyWhisperMessageProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/WhisperTextProtocol.proto").build("textsecure.PreKeyWhisperMessage");
|
|
||||||
self.decodePreKeyWhisperMessageProtobuf = function(string) {
|
|
||||||
return self.PreKeyWhisperMessageProtobuf.decode(btoa(string));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.DeviceInitProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/DeviceMessages.proto").build("textsecure.DeviceInit");
|
|
||||||
self.decodeDeviceInitProtobuf = function(string) {
|
|
||||||
return self.DeviceInitProtobuf.decode(btoa(string));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.IdentityKeyProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/DeviceMessages.proto").build("textsecure.IdentityKey");
|
|
||||||
self.decodeIdentityKeyProtobuf = function(string) {
|
|
||||||
return self.IdentityKeyProtobuf.decode(btoa(string));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.DeviceControlProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/DeviceMessages.proto").build("textsecure.DeviceControl");
|
|
||||||
self.decodeDeviceControlProtobuf = function(string) {
|
|
||||||
return self.DeviceControlProtobuf.decode(btoa(string));
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}();
|
|
||||||
|
|
||||||
// Number formatting utils
|
// Number formatting utils
|
||||||
window.textsecure.utils = function() {
|
window.textsecure.utils = function() {
|
||||||
var self = {};
|
var self = {};
|
||||||
|
@ -611,7 +568,7 @@ window.textsecure.subscribeToPush = function(message_callback) {
|
||||||
|
|
||||||
socket.onmessage = function(message) {
|
socket.onmessage = function(message) {
|
||||||
textsecure.crypto.decryptWebsocketMessage(message.message).then(function(plaintext) {
|
textsecure.crypto.decryptWebsocketMessage(message.message).then(function(plaintext) {
|
||||||
var proto = textsecure.protos.decodeIncomingPushMessageProtobuf(getString(plaintext));
|
var proto = textsecure.protobuf.IncomingPushMessageSignal.decode(plaintext);
|
||||||
// After this point, a) decoding errors are not the server's fault, and
|
// After this point, a) decoding errors are not the server's fault, and
|
||||||
// b) we should handle them gracefully and tell the user they received an invalid message
|
// b) we should handle them gracefully and tell the user they received an invalid message
|
||||||
console.log("Successfully decoded message with id: " + message.id);
|
console.log("Successfully decoded message with id: " + message.id);
|
||||||
|
@ -629,8 +586,8 @@ window.textsecure.subscribeToPush = function(message_callback) {
|
||||||
if (decrypted.flags == null)
|
if (decrypted.flags == null)
|
||||||
decrypted.flags = 0;
|
decrypted.flags = 0;
|
||||||
|
|
||||||
if ((decrypted.flags & textsecure.protos.PushMessageContentProtobuf.Flags.END_SESSION)
|
if ((decrypted.flags & textsecure.protobuf.PushMessageContent.Flags.END_SESSION)
|
||||||
== textsecure.protos.PushMessageContentProtobuf.Flags.END_SESSION)
|
== textsecure.protobuf.PushMessageContent.Flags.END_SESSION)
|
||||||
return;
|
return;
|
||||||
if (decrypted.flags != 0)
|
if (decrypted.flags != 0)
|
||||||
throw new Error("Unknown flags in message");
|
throw new Error("Unknown flags in message");
|
||||||
|
@ -649,7 +606,7 @@ window.textsecure.subscribeToPush = function(message_callback) {
|
||||||
decrypted.group.id = getString(decrypted.group.id);
|
decrypted.group.id = getString(decrypted.group.id);
|
||||||
var existingGroup = textsecure.storage.groups.getNumbers(decrypted.group.id);
|
var existingGroup = textsecure.storage.groups.getNumbers(decrypted.group.id);
|
||||||
if (existingGroup === undefined) {
|
if (existingGroup === undefined) {
|
||||||
if (decrypted.group.type != textsecure.protos.PushMessageContentProtobuf.GroupContext.Type.UPDATE)
|
if (decrypted.group.type != textsecure.protobuf.PushMessageContent.GroupContext.Type.UPDATE)
|
||||||
throw new Error("Got message for unknown group");
|
throw new Error("Got message for unknown group");
|
||||||
textsecure.storage.groups.createNewGroup(decrypted.group.members, decrypted.group.id);
|
textsecure.storage.groups.createNewGroup(decrypted.group.members, decrypted.group.id);
|
||||||
} else {
|
} else {
|
||||||
|
@ -659,7 +616,7 @@ window.textsecure.subscribeToPush = function(message_callback) {
|
||||||
throw new Error("Sender was not a member of the group they were sending from");
|
throw new Error("Sender was not a member of the group they were sending from");
|
||||||
|
|
||||||
switch(decrypted.group.type) {
|
switch(decrypted.group.type) {
|
||||||
case textsecure.protos.PushMessageContentProtobuf.GroupContext.Type.UPDATE:
|
case textsecure.protobuf.PushMessageContent.GroupContext.Type.UPDATE:
|
||||||
if (decrypted.group.avatar !== null)
|
if (decrypted.group.avatar !== null)
|
||||||
promises.push(handleAttachment(decrypted.group.avatar));
|
promises.push(handleAttachment(decrypted.group.avatar));
|
||||||
|
|
||||||
|
@ -682,12 +639,12 @@ window.textsecure.subscribeToPush = function(message_callback) {
|
||||||
decrypted.attachments = [];
|
decrypted.attachments = [];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case textsecure.protos.PushMessageContentProtobuf.GroupContext.Type.QUIT:
|
case textsecure.protobuf.PushMessageContent.GroupContext.Type.QUIT:
|
||||||
textsecure.storage.groups.removeNumber(decrypted.group.id, proto.source);
|
textsecure.storage.groups.removeNumber(decrypted.group.id, proto.source);
|
||||||
|
|
||||||
decrypted.body = null;
|
decrypted.body = null;
|
||||||
decrypted.attachments = [];
|
decrypted.attachments = [];
|
||||||
case textsecure.protos.PushMessageContentProtobuf.GroupContext.Type.DELIVER:
|
case textsecure.protobuf.PushMessageContent.GroupContext.Type.DELIVER:
|
||||||
decrypted.group.name = null;
|
decrypted.group.name = null;
|
||||||
decrypted.group.members = [];
|
decrypted.group.members = [];
|
||||||
decrypted.group.avatar = null;
|
decrypted.group.avatar = null;
|
||||||
|
@ -741,7 +698,7 @@ window.textsecure.registerSingleDevice = function(number, verificationCode, step
|
||||||
}
|
}
|
||||||
|
|
||||||
window.textsecure.registerSecondDevice = function(encodedDeviceInit, cryptoInfo, stepDone) {
|
window.textsecure.registerSecondDevice = function(encodedDeviceInit, cryptoInfo, stepDone) {
|
||||||
var deviceInit = textsecure.protos.decodeDeviceInit(encodedDeviceInit);
|
var deviceInit = textsecure.protobuf.DeviceInit.decode(encodedDeviceInit, 'binary');
|
||||||
return cryptoInfo.decryptAndHandleDeviceInit(deviceInit).then(function(identityKey) {
|
return cryptoInfo.decryptAndHandleDeviceInit(deviceInit).then(function(identityKey) {
|
||||||
if (identityKey.server != textsecure.api.relay)
|
if (identityKey.server != textsecure.api.relay)
|
||||||
throw new Error("Unknown relay used by master");
|
throw new Error("Unknown relay used by master");
|
||||||
|
|
21
js/protobufs.js
Normal file
21
js/protobufs.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
;(function() {
|
||||||
|
|
||||||
|
function loadProtoBufs(filename) {
|
||||||
|
return dcodeIO.ProtoBuf.loadProtoFile({root: 'protos', file: filename}).build('textsecure');
|
||||||
|
};
|
||||||
|
|
||||||
|
var pushMessages = loadProtoBufs('IncomingPushMessageSignal.proto');
|
||||||
|
var protocolMessages = loadProtoBufs('WhisperTextProtocol.proto');
|
||||||
|
var deviceMessages = loadProtoBufs('DeviceMessages.proto');
|
||||||
|
|
||||||
|
window.textsecure = window.textsecure || {};
|
||||||
|
window.textsecure.protobuf = {
|
||||||
|
IncomingPushMessageSignal : pushMessages.IncomingPushMessageSignal,
|
||||||
|
PushMessageContent : pushMessages.PushMessageContent,
|
||||||
|
WhisperMessage : protocolMessages.WhisperMessage,
|
||||||
|
PreKeyWhisperMessage : protocolMessages.PreKeyWhisperMessage,
|
||||||
|
DeviceInit : deviceMessages.DeviceInit,
|
||||||
|
IdentityKey : deviceMessages.IdentityKey,
|
||||||
|
DeviceControl : deviceMessages.DeviceControl
|
||||||
|
};
|
||||||
|
})();
|
|
@ -79,11 +79,11 @@ window.textsecure.messaging = function() {
|
||||||
for (var i in groups) {
|
for (var i in groups) {
|
||||||
var group = textsecure.storage.groups.getGroup(groups[i]);
|
var group = textsecure.storage.groups.getGroup(groups[i]);
|
||||||
|
|
||||||
var proto = new textsecure.protos.PushMessageContentProtobuf();
|
var proto = new textsecure.protobuf.PushMessageContent();
|
||||||
proto.group = new textsecure.protos.PushMessageContentProtobuf.GroupContext();
|
proto.group = new textsecure.protobuf.PushMessageContent.GroupContext();
|
||||||
|
|
||||||
proto.group.id = toArrayBuffer(group.id);
|
proto.group.id = toArrayBuffer(group.id);
|
||||||
proto.group.type = textsecure.protos.PushMessageContentProtobuf.GroupContext.Type.UPDATE;
|
proto.group.type = textsecure.protobuf.PushMessageContent.GroupContext.Type.UPDATE;
|
||||||
proto.group.members = group.numbers;
|
proto.group.members = group.numbers;
|
||||||
proto.group.name = group.name === undefined ? null : group.name;
|
proto.group.name = group.name === undefined ? null : group.name;
|
||||||
|
|
||||||
|
@ -102,10 +102,10 @@ window.textsecure.messaging = function() {
|
||||||
var tryMessageAgain = function(number, encodedMessage, callback) {
|
var tryMessageAgain = function(number, encodedMessage, callback) {
|
||||||
//TODO: Wipe identity key!
|
//TODO: Wipe identity key!
|
||||||
refreshGroups(number).then(function() {
|
refreshGroups(number).then(function() {
|
||||||
var message = textsecure.protos.decodePushMessageContentProtobuf(encodedMessage);
|
var message = textsecure.protobuf.PushMessageContent.decode(encodedMessage, 'binary');
|
||||||
textsecure.sendMessage([number], message, callback);
|
textsecure.sendMessage([number], message, callback);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
textsecure.replay.registerReplayFunction(tryMessageAgain, textsecure.replay.SEND_MESSAGE);
|
textsecure.replay.registerReplayFunction(tryMessageAgain, textsecure.replay.SEND_MESSAGE);
|
||||||
|
|
||||||
var sendMessageProto = function(numbers, message, callback) {
|
var sendMessageProto = function(numbers, message, callback) {
|
||||||
|
@ -194,7 +194,7 @@ window.textsecure.messaging = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
makeAttachmentPointer = function(attachment) {
|
makeAttachmentPointer = function(attachment) {
|
||||||
var proto = new textsecure.protos.PushMessageContentProtobuf.AttachmentPointer();
|
var proto = new textsecure.protobuf.PushMessageContent.AttachmentPointer();
|
||||||
proto.key = textsecure.crypto.getRandomBytes(64);
|
proto.key = textsecure.crypto.getRandomBytes(64);
|
||||||
|
|
||||||
var iv = textsecure.crypto.getRandomBytes(16);
|
var iv = textsecure.crypto.getRandomBytes(16);
|
||||||
|
@ -233,7 +233,7 @@ window.textsecure.messaging = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.sendMessageToNumber = function(number, messageText, attachments) {
|
self.sendMessageToNumber = function(number, messageText, attachments) {
|
||||||
var proto = new textsecure.protos.PushMessageContentProtobuf();
|
var proto = new textsecure.protobuf.PushMessageContent();
|
||||||
proto.body = messageText;
|
proto.body = messageText;
|
||||||
|
|
||||||
var promises = [];
|
var promises = [];
|
||||||
|
@ -246,9 +246,9 @@ window.textsecure.messaging = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.closeSession = function(number) {
|
self.closeSession = function(number) {
|
||||||
var proto = new textsecure.protos.PushMessageContentProtobuf();
|
var proto = new textsecure.protobuf.PushMessageContent();
|
||||||
proto.body = "TERMINATE";
|
proto.body = "TERMINATE";
|
||||||
proto.flags = textsecure.protos.PushMessageContentProtobuf.Flags.END_SESSION;
|
proto.flags = textsecure.protobuf.PushMessageContent.Flags.END_SESSION;
|
||||||
return sendIndividualProto(number, proto).then(function(res) {
|
return sendIndividualProto(number, proto).then(function(res) {
|
||||||
var devices = textsecure.storage.devices.getDeviceObjectsForNumber(number);
|
var devices = textsecure.storage.devices.getDeviceObjectsForNumber(number);
|
||||||
for (var i in devices)
|
for (var i in devices)
|
||||||
|
@ -259,11 +259,11 @@ window.textsecure.messaging = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.sendMessageToGroup = function(groupId, messageText, attachments) {
|
self.sendMessageToGroup = function(groupId, messageText, attachments) {
|
||||||
var proto = new textsecure.protos.PushMessageContentProtobuf();
|
var proto = new textsecure.protobuf.PushMessageContent();
|
||||||
proto.body = messageText;
|
proto.body = messageText;
|
||||||
proto.group = new textsecure.protos.PushMessageContentProtobuf.GroupContext();
|
proto.group = new textsecure.protobuf.PushMessageContent.GroupContext();
|
||||||
proto.group.id = toArrayBuffer(groupId);
|
proto.group.id = toArrayBuffer(groupId);
|
||||||
proto.group.type = textsecure.protos.PushMessageContentProtobuf.GroupContext.Type.DELIVER;
|
proto.group.type = textsecure.protobuf.PushMessageContent.GroupContext.Type.DELIVER;
|
||||||
|
|
||||||
var numbers = textsecure.storage.groups.getNumbers(groupId);
|
var numbers = textsecure.storage.groups.getNumbers(groupId);
|
||||||
if (numbers === undefined)
|
if (numbers === undefined)
|
||||||
|
@ -279,14 +279,14 @@ window.textsecure.messaging = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.createGroup = function(numbers, name, avatar) {
|
self.createGroup = function(numbers, name, avatar) {
|
||||||
var proto = new textsecure.protos.PushMessageContentProtobuf();
|
var proto = new textsecure.protobuf.PushMessageContent();
|
||||||
proto.group = new textsecure.protos.PushMessageContentProtobuf.GroupContext();
|
proto.group = new textsecure.protobuf.PushMessageContent.GroupContext();
|
||||||
|
|
||||||
var group = textsecure.storage.groups.createNewGroup(numbers);
|
var group = textsecure.storage.groups.createNewGroup(numbers);
|
||||||
proto.group.id = toArrayBuffer(group.id);
|
proto.group.id = toArrayBuffer(group.id);
|
||||||
var numbers = group.numbers;
|
var numbers = group.numbers;
|
||||||
|
|
||||||
proto.group.type = textsecure.protos.PushMessageContentProtobuf.GroupContext.Type.UPDATE;
|
proto.group.type = textsecure.protobuf.PushMessageContent.GroupContext.Type.UPDATE;
|
||||||
proto.group.members = numbers;
|
proto.group.members = numbers;
|
||||||
proto.group.name = name;
|
proto.group.name = name;
|
||||||
|
|
||||||
|
@ -305,10 +305,10 @@ window.textsecure.messaging = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.addNumberToGroup = function(groupId, number) {
|
self.addNumberToGroup = function(groupId, number) {
|
||||||
var proto = new textsecure.protos.PushMessageContentProtobuf();
|
var proto = new textsecure.protobuf.PushMessageContent();
|
||||||
proto.group = new textsecure.protos.PushMessageContentProtobuf.GroupContext();
|
proto.group = new textsecure.protobuf.PushMessageContent.GroupContext();
|
||||||
proto.group.id = toArrayBuffer(groupId);
|
proto.group.id = toArrayBuffer(groupId);
|
||||||
proto.group.type = textsecure.protos.PushMessageContentProtobuf.GroupContext.Type.UPDATE;
|
proto.group.type = textsecure.protobuf.PushMessageContent.GroupContext.Type.UPDATE;
|
||||||
|
|
||||||
var numbers = textsecure.storage.groups.addNumbers(groupId, [number]);
|
var numbers = textsecure.storage.groups.addNumbers(groupId, [number]);
|
||||||
if (numbers === undefined)
|
if (numbers === undefined)
|
||||||
|
@ -319,10 +319,10 @@ window.textsecure.messaging = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.setGroupName = function(groupId, name) {
|
self.setGroupName = function(groupId, name) {
|
||||||
var proto = new textsecure.protos.PushMessageContentProtobuf();
|
var proto = new textsecure.protobuf.PushMessageContent();
|
||||||
proto.group = new textsecure.protos.PushMessageContentProtobuf.GroupContext();
|
proto.group = new textsecure.protobuf.PushMessageContent.GroupContext();
|
||||||
proto.group.id = toArrayBuffer(groupId);
|
proto.group.id = toArrayBuffer(groupId);
|
||||||
proto.group.type = textsecure.protos.PushMessageContentProtobuf.GroupContext.Type.UPDATE;
|
proto.group.type = textsecure.protobuf.PushMessageContent.GroupContext.Type.UPDATE;
|
||||||
proto.group.name = name;
|
proto.group.name = name;
|
||||||
|
|
||||||
var numbers = textsecure.storage.groups.getNumbers(groupId);
|
var numbers = textsecure.storage.groups.getNumbers(groupId);
|
||||||
|
@ -334,10 +334,10 @@ window.textsecure.messaging = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.setGroupAvatar = function(groupId, avatar) {
|
self.setGroupAvatar = function(groupId, avatar) {
|
||||||
var proto = new textsecure.protos.PushMessageContentProtobuf();
|
var proto = new textsecure.protobuf.PushMessageContent();
|
||||||
proto.group = new textsecure.protos.PushMessageContentProtobuf.GroupContext();
|
proto.group = new textsecure.protobuf.PushMessageContent.GroupContext();
|
||||||
proto.group.id = toArrayBuffer(groupId);
|
proto.group.id = toArrayBuffer(groupId);
|
||||||
proto.group.type = textsecure.protos.PushMessageContentProtobuf.GroupContext.Type.UPDATE;
|
proto.group.type = textsecure.protobuf.PushMessageContent.GroupContext.Type.UPDATE;
|
||||||
|
|
||||||
var numbers = textsecure.storage.groups.getNumbers(groupId);
|
var numbers = textsecure.storage.groups.getNumbers(groupId);
|
||||||
if (numbers === undefined)
|
if (numbers === undefined)
|
||||||
|
@ -351,10 +351,10 @@ window.textsecure.messaging = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.leaveGroup = function(groupId) {
|
self.leaveGroup = function(groupId) {
|
||||||
var proto = new textsecure.protos.PushMessageContentProtobuf();
|
var proto = new textsecure.protobuf.PushMessageContent();
|
||||||
proto.group = new textsecure.protos.PushMessageContentProtobuf.GroupContext();
|
proto.group = new textsecure.protobuf.PushMessageContent.GroupContext();
|
||||||
proto.group.id = toArrayBuffer(groupId);
|
proto.group.id = toArrayBuffer(groupId);
|
||||||
proto.group.type = textsecure.protos.PushMessageContentProtobuf.GroupContext.Type.QUIT;
|
proto.group.type = textsecure.protobuf.PushMessageContent.GroupContext.Type.QUIT;
|
||||||
|
|
||||||
var numbers = textsecure.storage.groups.getNumbers(groupId);
|
var numbers = textsecure.storage.groups.getNumbers(groupId);
|
||||||
if (numbers === undefined)
|
if (numbers === undefined)
|
||||||
|
|
11
js/test.js
11
js/test.js
|
@ -291,15 +291,16 @@ describe("Axolotl", function() {
|
||||||
if (data.newEphemeralKey !== undefined)
|
if (data.newEphemeralKey !== undefined)
|
||||||
privKeyQueue.push(data.newEphemeralKey);
|
privKeyQueue.push(data.newEphemeralKey);
|
||||||
|
|
||||||
var message = new textsecure.protos.IncomingPushMessageProtobuf();
|
var message = new textsecure.protobuf.IncomingPushMessageSignal();
|
||||||
message.type = data.type;
|
message.type = data.type;
|
||||||
message.source = "SNOWDEN";
|
message.source = "SNOWDEN";
|
||||||
message.message = data.message;
|
message.message = data.message;
|
||||||
message.sourceDevice = 1;
|
message.sourceDevice = 1;
|
||||||
try {
|
try {
|
||||||
return textsecure.crypto.handleIncomingPushMessageProto(textsecure.protos.decodeIncomingPushMessageProtobuf(getString(message.encode()))).then(function(res) {
|
var proto = textsecure.protobuf.IncomingPushMessageSignal.decode(message.encode());
|
||||||
|
return textsecure.crypto.handleIncomingPushMessageProto(proto).then(function(res) {
|
||||||
if (data.expectTerminateSession)
|
if (data.expectTerminateSession)
|
||||||
return res.flags == textsecure.protos.PushMessageContentProtobuf.Flags.END_SESSION;
|
return res.flags == textsecure.protobuf.PushMessageContent.Flags.END_SESSION;
|
||||||
return res.body == data.expectedSmsText;
|
return res.body == data.expectedSmsText;
|
||||||
}).catch(function(e) {
|
}).catch(function(e) {
|
||||||
if (data.expectException)
|
if (data.expectException)
|
||||||
|
@ -345,11 +346,11 @@ describe("Axolotl", function() {
|
||||||
//XXX: This should be all we do: isEqual(data.expectedCiphertext, msg.body, false);
|
//XXX: This should be all we do: isEqual(data.expectedCiphertext, msg.body, false);
|
||||||
if (msg.type == 1) {
|
if (msg.type == 1) {
|
||||||
var expected = getString(data.expectedCiphertext);
|
var expected = getString(data.expectedCiphertext);
|
||||||
var decoded = textsecure.protos.decodeWhisperMessageProtobuf(expected.substring(1, expected.length - 8));
|
var decoded = textsecure.protobuf.WhisperMessage.decode(expected.substring(1, expected.length - 8), 'binary');
|
||||||
var result = getString(msg.body);
|
var result = getString(msg.body);
|
||||||
return getString(decoded.encode()) == result.substring(1, result.length - 8);
|
return getString(decoded.encode()) == result.substring(1, result.length - 8);
|
||||||
} else {
|
} else {
|
||||||
var decoded = textsecure.protos.decodePreKeyWhisperMessageProtobuf(getString(data.expectedCiphertext).substr(1));
|
var decoded = textsecure.protobuf.PreKeyWhisperMessage.decode(getString(data.expectedCiphertext).substr(1), 'binary');
|
||||||
var result = getString(msg.body).substring(1);
|
var result = getString(msg.body).substring(1);
|
||||||
return getString(decoded.encode()) == result;
|
return getString(decoded.encode()) == result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,7 @@
|
||||||
<script type="text/javascript" src="js-deps/libphonenumber_api-compiled.js"></script>
|
<script type="text/javascript" src="js-deps/libphonenumber_api-compiled.js"></script>
|
||||||
<script type="text/javascript" src="js-deps/qrcode.min.js"></script>
|
<script type="text/javascript" src="js-deps/qrcode.min.js"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="js/protobufs.js"></script>
|
||||||
<script type="text/javascript" src="js/helpers.js"></script>
|
<script type="text/javascript" src="js/helpers.js"></script>
|
||||||
<script type="text/javascript" src="js/libphonenumber-util.js"></script>
|
<script type="text/javascript" src="js/libphonenumber-util.js"></script>
|
||||||
<script type="text/javascript" src="js/webcrypto.js"></script>
|
<script type="text/javascript" src="js/webcrypto.js"></script>
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
<script type="text/javascript" src="js-deps/backbone.localStorage.js"></script>
|
<script type="text/javascript" src="js-deps/backbone.localStorage.js"></script>
|
||||||
<script type="text/javascript" src="js-deps/libphonenumber_api-compiled.js"></script>
|
<script type="text/javascript" src="js-deps/libphonenumber_api-compiled.js"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="js/protobufs.js" data-cover></script>
|
||||||
<script type="text/javascript" src="js/helpers.js" data-cover></script>
|
<script type="text/javascript" src="js/helpers.js" data-cover></script>
|
||||||
<script type="text/javascript" src="js/webcrypto.js"></script>
|
<script type="text/javascript" src="js/webcrypto.js"></script>
|
||||||
<script type="text/javascript" src="js/crypto.js" data-cover></script>
|
<script type="text/javascript" src="js/crypto.js" data-cover></script>
|
||||||
|
|
Loading…
Reference in a new issue