textsecure.protos
This commit is contained in:
		
					parent
					
						
							
								665f0ef00a
							
						
					
				
			
			
				commit
				
					
						9aae93fc99
					
				
			
		
					 4 changed files with 63 additions and 53 deletions
				
			
		
							
								
								
									
										12
									
								
								js/crypto.js
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								js/crypto.js
									
										
									
									
									
								
							|  | @ -523,7 +523,7 @@ window.textsecure.crypto = new 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 = decodeWhisperMessageProtobuf(messageProto); | 		var message = textsecure.protos.decodeWhisperMessageProtobuf(messageProto); | ||||||
| 		var remoteEphemeralKey = toArrayBuffer(message.ephemeralKey); | 		var remoteEphemeralKey = toArrayBuffer(message.ephemeralKey); | ||||||
| 
 | 
 | ||||||
| 		if (session === undefined) { | 		if (session === undefined) { | ||||||
|  | @ -547,7 +547,7 @@ window.textsecure.crypto = new function() { | ||||||
| 							removeOldChains(session); | 							removeOldChains(session); | ||||||
| 							delete session['pendingPreKey']; | 							delete session['pendingPreKey']; | ||||||
| 
 | 
 | ||||||
| 							var finalMessage = decodePushMessageContentProtobuf(getString(plaintext)); | 							var finalMessage = textsecure.protos.decodePushMessageContentProtobuf(getString(plaintext)); | ||||||
| 
 | 
 | ||||||
| 							if ((finalMessage.flags & 1) == 1) // END_SESSION
 | 							if ((finalMessage.flags & 1) == 1) // END_SESSION
 | ||||||
| 								closeSession(session); | 								closeSession(session); | ||||||
|  | @ -601,7 +601,7 @@ window.textsecure.crypto = new function() { | ||||||
| 	self.handleIncomingPushMessageProto = function(proto) { | 	self.handleIncomingPushMessageProto = function(proto) { | ||||||
| 		switch(proto.type) { | 		switch(proto.type) { | ||||||
| 		case 0: //TYPE_MESSAGE_PLAINTEXT
 | 		case 0: //TYPE_MESSAGE_PLAINTEXT
 | ||||||
| 			return Promise.resolve(decodePushMessageContentProtobuf(getString(proto.message))); | 			return Promise.resolve(textsecure.protos.decodePushMessageContentProtobuf(getString(proto.message))); | ||||||
| 		case 1: //TYPE_MESSAGE_CIPHERTEXT
 | 		case 1: //TYPE_MESSAGE_CIPHERTEXT
 | ||||||
| 			return decryptWhisperMessage(proto.source, getString(proto.message)).then(function(result) { | 			return decryptWhisperMessage(proto.source, getString(proto.message)).then(function(result) { | ||||||
|                 return {message:result, pushMessage: proto}; |                 return {message:result, pushMessage: proto}; | ||||||
|  | @ -609,7 +609,7 @@ window.textsecure.crypto = new function() { | ||||||
| 		case 3: //TYPE_MESSAGE_PREKEY_BUNDLE
 | 		case 3: //TYPE_MESSAGE_PREKEY_BUNDLE
 | ||||||
| 			if (proto.message.readUint8() != (2 << 4 | 2)) | 			if (proto.message.readUint8() != (2 << 4 | 2)) | ||||||
| 				throw new Error("Bad version byte"); | 				throw new Error("Bad version byte"); | ||||||
| 			var preKeyProto = decodePreKeyWhisperMessageProtobuf(getString(proto.message)); | 			var preKeyProto = textsecure.protos.decodePreKeyWhisperMessageProtobuf(getString(proto.message)); | ||||||
| 			return initSessionFromPreKeyWhisperMessage(proto.source, preKeyProto).then(function(sessions) { | 			return initSessionFromPreKeyWhisperMessage(proto.source, preKeyProto).then(function(sessions) { | ||||||
| 				return decryptWhisperMessage(proto.source, getString(preKeyProto.message), sessions[0]).then(function(result) { | 				return decryptWhisperMessage(proto.source, getString(preKeyProto.message), sessions[0]).then(function(result) { | ||||||
| 					if (sessions[1] !== undefined) | 					if (sessions[1] !== undefined) | ||||||
|  | @ -625,7 +625,7 @@ window.textsecure.crypto = new function() { | ||||||
| 		var session = crypto_storage.getOpenSession(deviceObject.encodedNumber); | 		var session = crypto_storage.getOpenSession(deviceObject.encodedNumber); | ||||||
| 
 | 
 | ||||||
| 		var doEncryptPushMessageContent = function() { | 		var doEncryptPushMessageContent = function() { | ||||||
| 			var msg = new WhisperMessageProtobuf(); | 			var msg = new textsecure.protos.WhisperMessageProtobuf(); | ||||||
| 			var plaintext = toArrayBuffer(pushMessageContent.encode()); | 			var plaintext = toArrayBuffer(pushMessageContent.encode()); | ||||||
| 
 | 
 | ||||||
| 			msg.ephemeralKey = toArrayBuffer(session.currentRatchet.ephemeralKeyPair.pubKey); | 			msg.ephemeralKey = toArrayBuffer(session.currentRatchet.ephemeralKeyPair.pubKey); | ||||||
|  | @ -655,7 +655,7 @@ window.textsecure.crypto = new function() { | ||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		var preKeyMsg = new PreKeyWhisperMessageProtobuf(); | 		var preKeyMsg = new textsecure.protos.PreKeyWhisperMessageProtobuf(); | ||||||
| 		preKeyMsg.identityKey = toArrayBuffer(crypto_storage.getStoredPubKey("identityKey")); | 		preKeyMsg.identityKey = toArrayBuffer(crypto_storage.getStoredPubKey("identityKey")); | ||||||
| 		preKeyMsg.preKeyId = deviceObject.preKeyId; | 		preKeyMsg.preKeyId = deviceObject.preKeyId; | ||||||
| 		preKeyMsg.registrationId = textsecure.storage.getUnencrypted("registrationId"); | 		preKeyMsg.registrationId = textsecure.storage.getUnencrypted("registrationId"); | ||||||
|  |  | ||||||
|  | @ -152,27 +152,6 @@ function toArrayBuffer(thing) { | ||||||
| 	return res; | 	return res; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function ensureStringed(thing) { |  | ||||||
| 	if (getStringable(thing)) |  | ||||||
| 		return getString(thing); |  | ||||||
| 	else if (thing instanceof Array) { |  | ||||||
| 		var res = []; |  | ||||||
| 		for (var i = 0; i < thing.length; i++) |  | ||||||
| 			res[i] = ensureStringed(thing[i]); |  | ||||||
| 		return res; |  | ||||||
| 	} else if (thing === Object(thing)) { |  | ||||||
| 		var res = {}; |  | ||||||
| 		for (key in thing) |  | ||||||
| 			res[key] = ensureStringed(thing[key]); |  | ||||||
| 		return res; |  | ||||||
| 	} |  | ||||||
| 	throw new Error("unsure of how to jsonify object of type " + typeof thing); |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function jsonThing(thing) { |  | ||||||
| 	return JSON.stringify(ensureStringed(thing)); |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| function base64ToArrayBuffer(string) { | function base64ToArrayBuffer(string) { | ||||||
| 	return base64DecToArr(string); | 	return base64DecToArr(string); | ||||||
|  | @ -180,30 +159,36 @@ function base64ToArrayBuffer(string) { | ||||||
| 
 | 
 | ||||||
| // Protobuf decoding
 | // Protobuf decoding
 | ||||||
| //TODO: throw on missing fields everywhere
 | //TODO: throw on missing fields everywhere
 | ||||||
| var IncomingPushMessageProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/IncomingPushMessageSignal.proto").build("textsecure.IncomingPushMessageSignal"); | window.textsecure.protos = function() { | ||||||
| function decodeIncomingPushMessageProtobuf(string) { | 	var self = {}; | ||||||
| 	return IncomingPushMessageProtobuf.decode(btoa(string)); |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| var PushMessageContentProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/IncomingPushMessageSignal.proto").build("textsecure.PushMessageContent"); | 	self.IncomingPushMessageProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/IncomingPushMessageSignal.proto").build("textsecure.IncomingPushMessageSignal"); | ||||||
| function decodePushMessageContentProtobuf(string) { | 	self.decodeIncomingPushMessageProtobuf = function(string) { | ||||||
| 	return PushMessageContentProtobuf.decode(btoa(string)); | 		return IncomingPushMessageProtobuf.decode(btoa(string)); | ||||||
| } | 	} | ||||||
| 
 | 
 | ||||||
| var WhisperMessageProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/WhisperTextProtocol.proto").build("textsecure.WhisperMessage"); | 	self.PushMessageContentProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/IncomingPushMessageSignal.proto").build("textsecure.PushMessageContent"); | ||||||
| function decodeWhisperMessageProtobuf(string) { | 	self.decodePushMessageContentProtobuf = function(string) { | ||||||
| 	return WhisperMessageProtobuf.decode(btoa(string)); | 		return PushMessageContentProtobuf.decode(btoa(string)); | ||||||
| } | 	} | ||||||
| 
 | 
 | ||||||
| var PreKeyWhisperMessageProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/WhisperTextProtocol.proto").build("textsecure.PreKeyWhisperMessage"); | 	self.WhisperMessageProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/WhisperTextProtocol.proto").build("textsecure.WhisperMessage"); | ||||||
| function decodePreKeyWhisperMessageProtobuf(string) { | 	self.decodeWhisperMessageProtobuf = function(string) { | ||||||
| 	return PreKeyWhisperMessageProtobuf.decode(btoa(string)); | 		return WhisperMessageProtobuf.decode(btoa(string)); | ||||||
| } | 	} | ||||||
| 
 | 
 | ||||||
| var KeyExchangeMessageProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/WhisperTextProtocol.proto").build("textsecure.KeyExchangeMessage"); | 	self.PreKeyWhisperMessageProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/WhisperTextProtocol.proto").build("textsecure.PreKeyWhisperMessage"); | ||||||
| function decodeKeyExchangeMessageProtobuf(string) { | 	self.decodePreKeyWhisperMessageProtobuf = function(string) { | ||||||
| 	return KeyExchangeMessageProtobuf.decode(btoa(string)); | 		return PreKeyWhisperMessageProtobuf.decode(btoa(string)); | ||||||
| } | 	} | ||||||
|  | 
 | ||||||
|  | 	self.KeyExchangeMessageProtobuf = dcodeIO.ProtoBuf.loadProtoFile("protos/WhisperTextProtocol.proto").build("textsecure.KeyExchangeMessage"); | ||||||
|  | 	self.decodeKeyExchangeMessageProtobuf = function(string) { | ||||||
|  | 		return KeyExchangeMessageProtobuf.decode(btoa(string)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return self; | ||||||
|  | }(); | ||||||
| 
 | 
 | ||||||
| // Number formatting
 | // Number formatting
 | ||||||
| function getNumberFromString(string) { | function getNumberFromString(string) { | ||||||
|  | @ -232,6 +217,31 @@ function verifyNumber(string) { | ||||||
| window.textsecure.storage = function() { | window.textsecure.storage = function() { | ||||||
| 	var self = {}; | 	var self = {}; | ||||||
| 
 | 
 | ||||||
|  | 	/**************************** | ||||||
|  | 	 *** Conversion Utilities *** | ||||||
|  | 	 ****************************/ | ||||||
|  | 	function ensureStringed(thing) { | ||||||
|  | 		if (getStringable(thing)) | ||||||
|  | 			return getString(thing); | ||||||
|  | 		else if (thing instanceof Array) { | ||||||
|  | 			var res = []; | ||||||
|  | 			for (var i = 0; i < thing.length; i++) | ||||||
|  | 				res[i] = ensureStringed(thing[i]); | ||||||
|  | 			return res; | ||||||
|  | 		} else if (thing === Object(thing)) { | ||||||
|  | 			var res = {}; | ||||||
|  | 			for (key in thing) | ||||||
|  | 				res[key] = ensureStringed(thing[key]); | ||||||
|  | 			return res; | ||||||
|  | 		} | ||||||
|  | 		throw new Error("unsure of how to jsonify object of type " + typeof thing); | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	function jsonThing(thing) { | ||||||
|  | 		return JSON.stringify(ensureStringed(thing)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	/***************************** | 	/***************************** | ||||||
| 	 *** Base Storage Routines *** | 	 *** Base Storage Routines *** | ||||||
| 	 *****************************/ | 	 *****************************/ | ||||||
|  | @ -426,7 +436,7 @@ window.textsecure.subscribeToPush = function() { | ||||||
| 				console.log("Got pong message"); | 				console.log("Got pong message"); | ||||||
| 			} else if (message.type === undefined && message.id !== undefined) { | 			} else if (message.type === undefined && message.id !== undefined) { | ||||||
| 				textsecure.crypto.decryptWebsocketMessage(message.message).then(function(plaintext) { | 				textsecure.crypto.decryptWebsocketMessage(message.message).then(function(plaintext) { | ||||||
| 					var proto = decodeIncomingPushMessageProtobuf(getString(plaintext)); | 					var proto = textsecure.protos.decodeIncomingPushMessageProtobuf(getString(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); | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ var Whisper = Whisper || {}; | ||||||
| 
 | 
 | ||||||
|   var Message  = Backbone.Model.extend({ |   var Message  = Backbone.Model.extend({ | ||||||
|     toProto: function() { |     toProto: function() { | ||||||
|       return new PushMessageContentProtobuf({body: this.get('body')}); |       return new textsecure.protos.PushMessageContentProtobuf({body: this.get('body')}); | ||||||
|     } |     } | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -336,11 +336,11 @@ textsecure.registerOnLoadFunction(function() { | ||||||
| 					if (data.newEphemeralKey !== undefined) | 					if (data.newEphemeralKey !== undefined) | ||||||
| 						privKeyQueue.push(data.newEphemeralKey); | 						privKeyQueue.push(data.newEphemeralKey); | ||||||
| 
 | 
 | ||||||
| 					var message = new IncomingPushMessageProtobuf(); | 					var message = new textsecure.protos.IncomingPushMessageProtobuf(); | ||||||
| 					message.type = data.type; | 					message.type = data.type; | ||||||
| 					message.source = remoteDevice.encodedNumber; | 					message.source = remoteDevice.encodedNumber; | ||||||
| 					message.message = data.message; | 					message.message = data.message; | ||||||
| 					return textsecure.crypto.handleIncomingPushMessageProto(decodeIncomingPushMessageProtobuf(getString(message.encode()))).then(function(res) { | 					return textsecure.crypto.handleIncomingPushMessageProto(textsecure.protos.decodeIncomingPushMessageProtobuf(getString(message.encode()))).then(function(res) { | ||||||
| 						return res.message.body == data.expectedSmsText; | 						return res.message.body == data.expectedSmsText; | ||||||
| 					}); | 					}); | ||||||
| 				} | 				} | ||||||
|  | @ -373,11 +373,11 @@ textsecure.registerOnLoadFunction(function() { | ||||||
| 						//XXX: This should be all we do: stepDone(getString(data.expectedCiphertext) == getString(res.body));
 | 						//XXX: This should be all we do: stepDone(getString(data.expectedCiphertext) == getString(res.body));
 | ||||||
| 						if (res.type == 1) { //XXX: This should be used for everything...
 | 						if (res.type == 1) { //XXX: This should be used for everything...
 | ||||||
| 							var expectedString = getString(data.expectedCiphertext); | 							var expectedString = getString(data.expectedCiphertext); | ||||||
| 							var decoded = decodeWhisperMessageProtobuf(expectedString.substring(1, expectedString.length - 8)); | 							var decoded = textsecure.protos.decodeWhisperMessageProtobuf(expectedString.substring(1, expectedString.length - 8)); | ||||||
| 							var result = getString(res.body); | 							var result = getString(res.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 = decodePreKeyWhisperMessageProtobuf(getString(data.expectedCiphertext).substr(1)); | 							var decoded = textsecure.protos.decodePreKeyWhisperMessageProtobuf(getString(data.expectedCiphertext).substr(1)); | ||||||
| 							var result = getString(res.body).substring(1); | 							var result = getString(res.body).substring(1); | ||||||
| 							return getString(decoded.encode()) == result; | 							return getString(decoded.encode()) == result; | ||||||
| 						} | 						} | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Matt Corallo
				Matt Corallo