diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 70d66eb1b..1790ea513 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -334,8 +334,7 @@ B63AF5CB1A1F757900D01AAD /* TSRegisterPrekeysRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = B63AF5B51A1F757900D01AAD /* TSRegisterPrekeysRequest.m */; }; B63AF5CC1A1F757900D01AAD /* TSRegisterWithTokenRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = B63AF5B71A1F757900D01AAD /* TSRegisterWithTokenRequest.m */; }; B63AF5CD1A1F757900D01AAD /* TSRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = B63AF5B91A1F757900D01AAD /* TSRequest.m */; }; - B63AF5CE1A1F757900D01AAD /* TSRequestAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = B63AF5BB1A1F757900D01AAD /* TSRequestAttachment.m */; }; - B63AF5CF1A1F757900D01AAD /* TSRequestAttachmentId.m in Sources */ = {isa = PBXBuildFile; fileRef = B63AF5BD1A1F757900D01AAD /* TSRequestAttachmentId.m */; }; + B63AF5CE1A1F757900D01AAD /* TSAttachementRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = B63AF5BB1A1F757900D01AAD /* TSAttachementRequest.m */; }; B63AF5D01A1F757900D01AAD /* TSSubmitMessageRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = B63AF5BF1A1F757900D01AAD /* TSSubmitMessageRequest.m */; }; B63AF5D11A1F757900D01AAD /* TSUploadAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = B63AF5C11A1F757900D01AAD /* TSUploadAttachment.m */; }; B63AF5D21A1F757900D01AAD /* TSNetworkManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B63AF5C31A1F757900D01AAD /* TSNetworkManager.m */; }; @@ -349,6 +348,7 @@ B684A46D19C3446200B11029 /* PushManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B684A46C19C3446200B11029 /* PushManagerTest.m */; }; B6850E5A1995A4710068E715 /* whisperFake.cer in Resources */ = {isa = PBXBuildFile; fileRef = B6850E591995A4710068E715 /* whisperFake.cer */; }; B69CD25119773E79005CE69A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B69CD25019773E79005CE69A /* XCTest.framework */; }; + B6A3EB4B1A423B3800B2236B /* TSAttachementAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = B6A3EB4A1A423B3800B2236B /* TSAttachementAdapter.m */; }; B6AE33BD1A1EB121003DF39D /* GroupModel.m in Sources */ = {isa = PBXBuildFile; fileRef = B6AE33BC1A1EB121003DF39D /* GroupModel.m */; }; B6B095E41A1D25C5008BFAA6 /* CryptographyTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = B6B095DE1A1D25C5008BFAA6 /* CryptographyTests.mm */; }; B6B095E51A1D25C5008BFAA6 /* TextSecureKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B095DF1A1D25C5008BFAA6 /* TextSecureKitTests.m */; }; @@ -393,12 +393,15 @@ B6B096941A1D25ED008BFAA6 /* NSString+escape.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B0965E1A1D25ED008BFAA6 /* NSString+escape.m */; }; B6B096951A1D25ED008BFAA6 /* NSURLSessionDataTask+StatusCode.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B096601A1D25ED008BFAA6 /* NSURLSessionDataTask+StatusCode.m */; }; B6B1013C196D213F007E3930 /* SignalKeyingStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B1013B196D213F007E3930 /* SignalKeyingStorage.m */; }; + B6B50AAB1A4192C500F8F607 /* TSMessagesManager+attachements.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B50AAA1A4192C500F8F607 /* TSMessagesManager+attachements.m */; }; B6B9ECFC198B31BA00C620D3 /* PushManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B9ECFB198B31BA00C620D3 /* PushManager.m */; }; B6C6AE551A305ED1006BAF8F /* redphone.cer in Resources */ = {isa = PBXBuildFile; fileRef = B6C6AE531A305ED1006BAF8F /* redphone.cer */; }; B6C6AE561A305ED1006BAF8F /* textsecure.cer in Resources */ = {isa = PBXBuildFile; fileRef = B6C6AE541A305ED1006BAF8F /* textsecure.cer */; }; B6C93C4E199567AD00EDF894 /* DebugLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = B6C93C4D199567AD00EDF894 /* DebugLogger.m */; }; B6CBF53F1A254BD1000D4184 /* ContactDetailCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B6CBF53E1A254BD1000D4184 /* ContactDetailCell.m */; }; B6E314C91A38FAAF00A41AFB /* TSFingerprintGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = B6E314C81A38FAAF00A41AFB /* TSFingerprintGenerator.m */; }; + B6FAAAE81A41BC6C007FEC1D /* TSAttachementPointer.m in Sources */ = {isa = PBXBuildFile; fileRef = B6FAAAE71A41BC6C007FEC1D /* TSAttachementPointer.m */; }; + B6FAAAEE1A41C918007FEC1D /* TSAttachementStream.m in Sources */ = {isa = PBXBuildFile; fileRef = B6FAAAED1A41C918007FEC1D /* TSAttachementStream.m */; }; B90418E6183E9DD40038554A /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B90418E5183E9DD40038554A /* DateUtil.m */; }; B90418E7183E9DD40038554A /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B90418E5183E9DD40038554A /* DateUtil.m */; }; B96A3100187DA1B600648F3E /* HelveticaNeueLTStd-Bd.otf in Resources */ = {isa = PBXBuildFile; fileRef = B96A30FE187DA1B600648F3E /* HelveticaNeueLTStd-Bd.otf */; }; @@ -941,10 +944,8 @@ B63AF5B71A1F757900D01AAD /* TSRegisterWithTokenRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSRegisterWithTokenRequest.m; sourceTree = ""; }; B63AF5B81A1F757900D01AAD /* TSRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSRequest.h; sourceTree = ""; }; B63AF5B91A1F757900D01AAD /* TSRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSRequest.m; sourceTree = ""; }; - B63AF5BA1A1F757900D01AAD /* TSRequestAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSRequestAttachment.h; sourceTree = ""; }; - B63AF5BB1A1F757900D01AAD /* TSRequestAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSRequestAttachment.m; sourceTree = ""; }; - B63AF5BC1A1F757900D01AAD /* TSRequestAttachmentId.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSRequestAttachmentId.h; sourceTree = ""; }; - B63AF5BD1A1F757900D01AAD /* TSRequestAttachmentId.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSRequestAttachmentId.m; sourceTree = ""; }; + B63AF5BA1A1F757900D01AAD /* TSAttachementRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSAttachementRequest.h; sourceTree = ""; }; + B63AF5BB1A1F757900D01AAD /* TSAttachementRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSAttachementRequest.m; sourceTree = ""; }; B63AF5BE1A1F757900D01AAD /* TSSubmitMessageRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSSubmitMessageRequest.h; sourceTree = ""; }; B63AF5BF1A1F757900D01AAD /* TSSubmitMessageRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSSubmitMessageRequest.m; sourceTree = ""; }; B63AF5C01A1F757900D01AAD /* TSUploadAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSUploadAttachment.h; sourceTree = ""; }; @@ -967,6 +968,8 @@ B684A46C19C3446200B11029 /* PushManagerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PushManagerTest.m; path = Signal/test/push/PushManagerTest.m; sourceTree = SOURCE_ROOT; }; B6850E591995A4710068E715 /* whisperFake.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = whisperFake.cer; sourceTree = ""; }; B69CD25019773E79005CE69A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + B6A3EB491A423B3800B2236B /* TSAttachementAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSAttachementAdapter.h; sourceTree = ""; }; + B6A3EB4A1A423B3800B2236B /* TSAttachementAdapter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSAttachementAdapter.m; sourceTree = ""; }; B6AE33BB1A1EB121003DF39D /* GroupModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GroupModel.h; sourceTree = ""; }; B6AE33BC1A1EB121003DF39D /* GroupModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GroupModel.m; sourceTree = ""; }; B6B095DE1A1D25C5008BFAA6 /* CryptographyTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CryptographyTests.mm; sourceTree = ""; }; @@ -1051,6 +1054,8 @@ B6B096601A1D25ED008BFAA6 /* NSURLSessionDataTask+StatusCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURLSessionDataTask+StatusCode.m"; sourceTree = ""; }; B6B1013A196D213F007E3930 /* SignalKeyingStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SignalKeyingStorage.h; sourceTree = ""; }; B6B1013B196D213F007E3930 /* SignalKeyingStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SignalKeyingStorage.m; sourceTree = ""; }; + B6B50AA91A4192C500F8F607 /* TSMessagesManager+attachements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "TSMessagesManager+attachements.h"; sourceTree = ""; }; + B6B50AAA1A4192C500F8F607 /* TSMessagesManager+attachements.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "TSMessagesManager+attachements.m"; sourceTree = ""; }; B6B9ECFA198B31BA00C620D3 /* PushManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PushManager.h; sourceTree = ""; }; B6B9ECFB198B31BA00C620D3 /* PushManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PushManager.m; sourceTree = ""; }; B6C6AE531A305ED1006BAF8F /* redphone.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = redphone.cer; sourceTree = ""; }; @@ -1061,6 +1066,10 @@ B6CBF53E1A254BD1000D4184 /* ContactDetailCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ContactDetailCell.m; path = "Signal/src/view controllers/ContactDetailCell.m"; sourceTree = SOURCE_ROOT; }; B6E314C71A38FAAF00A41AFB /* TSFingerprintGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSFingerprintGenerator.h; sourceTree = ""; }; B6E314C81A38FAAF00A41AFB /* TSFingerprintGenerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSFingerprintGenerator.m; sourceTree = ""; }; + B6FAAAE61A41BC6C007FEC1D /* TSAttachementPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TSAttachementPointer.h; path = Attachements/TSAttachementPointer.h; sourceTree = ""; }; + B6FAAAE71A41BC6C007FEC1D /* TSAttachementPointer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TSAttachementPointer.m; path = Attachements/TSAttachementPointer.m; sourceTree = ""; }; + B6FAAAEC1A41C918007FEC1D /* TSAttachementStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TSAttachementStream.h; path = Attachements/TSAttachementStream.h; sourceTree = ""; }; + B6FAAAED1A41C918007FEC1D /* TSAttachementStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TSAttachementStream.m; path = Attachements/TSAttachementStream.m; sourceTree = ""; }; B90418E4183E9DD40038554A /* DateUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateUtil.h; sourceTree = ""; }; B90418E5183E9DD40038554A /* DateUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DateUtil.m; sourceTree = ""; }; B96A30FE187DA1B600648F3E /* HelveticaNeueLTStd-Bd.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "HelveticaNeueLTStd-Bd.otf"; sourceTree = ""; }; @@ -2112,6 +2121,8 @@ B62D53F41A23CC8B009AAF82 /* TSMessageAdapters */ = { isa = PBXGroup; children = ( + B6A3EB491A423B3800B2236B /* TSAttachementAdapter.h */, + B6A3EB4A1A423B3800B2236B /* TSAttachementAdapter.m */, B62D53F51A23CCAD009AAF82 /* TSMessageAdapter.h */, B62D53F61A23CCAD009AAF82 /* TSMessageAdapter.m */, ); @@ -2219,10 +2230,8 @@ B63AF5B71A1F757900D01AAD /* TSRegisterWithTokenRequest.m */, B63AF5B81A1F757900D01AAD /* TSRequest.h */, B63AF5B91A1F757900D01AAD /* TSRequest.m */, - B63AF5BA1A1F757900D01AAD /* TSRequestAttachment.h */, - B63AF5BB1A1F757900D01AAD /* TSRequestAttachment.m */, - B63AF5BC1A1F757900D01AAD /* TSRequestAttachmentId.h */, - B63AF5BD1A1F757900D01AAD /* TSRequestAttachmentId.m */, + B63AF5BA1A1F757900D01AAD /* TSAttachementRequest.h */, + B63AF5BB1A1F757900D01AAD /* TSAttachementRequest.m */, B63AF5BE1A1F757900D01AAD /* TSSubmitMessageRequest.h */, B63AF5BF1A1F757900D01AAD /* TSSubmitMessageRequest.m */, B63AF5C01A1F757900D01AAD /* TSUploadAttachment.h */, @@ -2336,10 +2345,9 @@ B6B096001A1D25ED008BFAA6 /* Messages */ = { isa = PBXGroup; children = ( + B6FAAAE91A41C7CC007FEC1D /* Attachement */, B6B096011A1D25ED008BFAA6 /* IncomingPushMessageSignal.pb.h */, B6B096021A1D25ED008BFAA6 /* IncomingPushMessageSignal.pb.m */, - B6B096031A1D25ED008BFAA6 /* TSAttachement.h */, - B6B096041A1D25ED008BFAA6 /* TSAttachement.m */, B6B096051A1D25ED008BFAA6 /* TSCall.h */, B6B096061A1D25ED008BFAA6 /* TSCall.m */, B6B096071A1D25ED008BFAA6 /* TSErrorMessage.h */, @@ -2360,6 +2368,8 @@ B6B096141A1D25ED008BFAA6 /* TSMessagesManager+sendMessages.m */, B6B096151A1D25ED008BFAA6 /* TSMessagesManager.h */, B6B096161A1D25ED008BFAA6 /* TSMessagesManager.m */, + B6B50AA91A4192C500F8F607 /* TSMessagesManager+attachements.h */, + B6B50AAA1A4192C500F8F607 /* TSMessagesManager+attachements.m */, B6B096171A1D25ED008BFAA6 /* TSOutgoingMessage.h */, B6B096181A1D25ED008BFAA6 /* TSOutgoingMessage.m */, B6B096191A1D25ED008BFAA6 /* TSServerMessage.h */, @@ -2451,6 +2461,19 @@ path = Certificates; sourceTree = ""; }; + B6FAAAE91A41C7CC007FEC1D /* Attachement */ = { + isa = PBXGroup; + children = ( + B6B096031A1D25ED008BFAA6 /* TSAttachement.h */, + B6B096041A1D25ED008BFAA6 /* TSAttachement.m */, + B6FAAAEC1A41C918007FEC1D /* TSAttachementStream.h */, + B6FAAAED1A41C918007FEC1D /* TSAttachementStream.m */, + B6FAAAE61A41BC6C007FEC1D /* TSAttachementPointer.h */, + B6FAAAE71A41BC6C007FEC1D /* TSAttachementPointer.m */, + ); + name = Attachement; + sourceTree = ""; + }; BF8C3D8119CE3B6A008F644C /* call */ = { isa = PBXGroup; children = ( @@ -3104,6 +3127,7 @@ 76EB063C18170B33006006FC /* NumberUtil.m in Sources */, B6B096691A1D25ED008BFAA6 /* TSThread.m in Sources */, B6B096641A1D25ED008BFAA6 /* TSContactThread.m in Sources */, + B6A3EB4B1A423B3800B2236B /* TSAttachementAdapter.m in Sources */, 76EB063A18170B33006006FC /* FunctionalUtil.m in Sources */, 76EB060A18170B33006006FC /* SignalUtil.m in Sources */, 76EB062818170B33006006FC /* BadArgument.m in Sources */, @@ -3142,10 +3166,11 @@ 76EB05DA18170B33006006FC /* LowLatencyConnector.m in Sources */, 76EB05EE18170B33006006FC /* CallTermination.m in Sources */, E1CD329618BCFF9900B1A496 /* SoundInstance.m in Sources */, + B6FAAAEE1A41C918007FEC1D /* TSAttachementStream.m in Sources */, 76EB05B418170B33006006FC /* HashChain.m in Sources */, 76EB05E418170B33006006FC /* UdpSocket.m in Sources */, B6B096931A1D25ED008BFAA6 /* NSData+messagePadding.m in Sources */, - B63AF5CE1A1F757900D01AAD /* TSRequestAttachment.m in Sources */, + B63AF5CE1A1F757900D01AAD /* TSAttachementRequest.m in Sources */, 76EB058218170B33006006FC /* Environment.m in Sources */, 76EB064418170B33006006FC /* ThreadManager.m in Sources */, E197B61E18BBEC6D00F073E5 /* AudioRouter.m in Sources */, @@ -3201,7 +3226,9 @@ 7038632718F70C0700D4A43F /* CryptoTools.m in Sources */, 76EB058C18170B33006006FC /* DnsManager.m in Sources */, B63AF5CB1A1F757900D01AAD /* TSRegisterPrekeysRequest.m in Sources */, + B6FAAAE81A41BC6C007FEC1D /* TSAttachementPointer.m in Sources */, B6B096881A1D25ED008BFAA6 /* TSStorageManager+keyFromIntLong.m in Sources */, + B6B50AAB1A4192C500F8F607 /* TSMessagesManager+attachements.m in Sources */, 76EB059018170B33006006FC /* IgnoredPacketFailure.m in Sources */, 765052AF182AC9B5008313E1 /* DialerButtonView.m in Sources */, 76EB05D418170B33006006FC /* ZrtpManager.m in Sources */, @@ -3273,7 +3300,6 @@ 76EB05AE18170B33006006FC /* SrtpStream.m in Sources */, B6B096711A1D25ED008BFAA6 /* TSInteraction.m in Sources */, B6B0966D1A1D25ED008BFAA6 /* TSErrorMessage.m in Sources */, - B63AF5CF1A1F757900D01AAD /* TSRequestAttachmentId.m in Sources */, E197B61318BBEC1A00F073E5 /* DesiredBufferDepthController.m in Sources */, 76EB064818170B33006006FC /* Zid.m in Sources */, B6B096741A1D25ED008BFAA6 /* TSMessagesManager.m in Sources */, diff --git a/Signal/src/textsecure/Messages/Attachements/TSAttachementPointer.h b/Signal/src/textsecure/Messages/Attachements/TSAttachementPointer.h new file mode 100644 index 000000000..cfbca7b79 --- /dev/null +++ b/Signal/src/textsecure/Messages/Attachements/TSAttachementPointer.h @@ -0,0 +1,22 @@ +// +// TSAttachementPointer.h +// Signal +// +// Created by Frederic Jacobs on 17/12/14. +// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// + +#import + +#import "TSAttachement.h" + +@interface TSAttachementPointer : TSAttachement + +- (instancetype)initWithIdentifier:(uint64_t)identifier + key:(NSData*)key + contentType:(NSString*)contentType + relay:(NSString*)relay; + +@property NSString *relay; + +@end diff --git a/Signal/src/textsecure/Messages/Attachements/TSAttachementPointer.m b/Signal/src/textsecure/Messages/Attachements/TSAttachementPointer.m new file mode 100644 index 000000000..52c93a3ea --- /dev/null +++ b/Signal/src/textsecure/Messages/Attachements/TSAttachementPointer.m @@ -0,0 +1,32 @@ +// +// TSAttachementPointer.m +// Signal +// +// Created by Frederic Jacobs on 17/12/14. +// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// + +#import "TSAttachementPointer.h" + +@implementation TSAttachementPointer + +- (instancetype)initWithIdentifier:(uint64_t)identifier + key:(NSData*)key + contentType:(NSString*)contentType + relay:(NSString*)relay +{ + self = [super initWithIdentifier:[[NSNumber numberWithUnsignedLongLong:identifier] stringValue] encryptionKey:key contentType:contentType]; + + if (self) { + self.relay = relay; + } + + return self; +} + +- (BOOL)isDownloaded{ + return NO; +} + + +@end diff --git a/Signal/src/textsecure/Messages/Attachements/TSAttachementStream.h b/Signal/src/textsecure/Messages/Attachements/TSAttachementStream.h new file mode 100644 index 000000000..e56ad0ac6 --- /dev/null +++ b/Signal/src/textsecure/Messages/Attachements/TSAttachementStream.h @@ -0,0 +1,25 @@ +// +// TSAttachementStream.h +// Signal +// +// Created by Frederic Jacobs on 17/12/14. +// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// + +#import "TSAttachement.h" + +@interface TSAttachementStream : TSAttachement + +- (instancetype)initWithIdentifier:(NSString*)identifier + data:(NSData*)data + key:(NSData*)key + contentType:(NSString*)contentType; + +- (NSString*)path; + +- (BOOL)isImage; +- (UIImage*)image; + +- (BOOL)isVideo; + +@end diff --git a/Signal/src/textsecure/Messages/Attachements/TSAttachementStream.m b/Signal/src/textsecure/Messages/Attachements/TSAttachementStream.m new file mode 100644 index 000000000..d91952c7b --- /dev/null +++ b/Signal/src/textsecure/Messages/Attachements/TSAttachementStream.m @@ -0,0 +1,73 @@ +// +// TSAttachementStream.m +// Signal +// +// Created by Frederic Jacobs on 17/12/14. +// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// + +#import "TSAttachementStream.h" + +@interface TSAttachementStream () + +@property (nonatomic) NSString *path; + +@end + +@implementation TSAttachementStream + +- (instancetype)initWithIdentifier:(NSString*)identifier + data:(NSData*)data + key:(NSData*)key + contentType:(NSString*)contentType{ + self = [super initWithIdentifier:identifier encryptionKey:key contentType:contentType]; + + NSString *path = [self filePath]; + [[NSFileManager defaultManager] createFileAtPath:path contents:data attributes:nil]; + + return self; +} + +- (BOOL)isDownloaded{ + return YES; +} + ++ (NSString*)attachmentsFolder { + NSFileManager* fileManager = [NSFileManager defaultManager]; + NSURL *fileURL = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; + NSString *path = [fileURL path]; + NSString *attachementFolder = [path stringByAppendingFormat:@"/Attachements"]; + + NSError * error = nil; + [[NSFileManager defaultManager] createDirectoryAtPath:attachementFolder + withIntermediateDirectories:YES + attributes:nil + error:&error]; + if (error != nil) { + DDLogError(@"Failed to create attachments directory: %@", error.description); + } + + return attachementFolder; +} + +- (NSString*)filePath { + return [[[self class] attachmentsFolder] stringByAppendingFormat:@"/%@", self.uniqueId]; +} + +- (BOOL)isImage{ + if ([self.contentType containsString:@"image/"]) { + return YES; + } else{ + return NO; + } +} + +- (UIImage*)image{ + if (![self isImage]) { + return nil; + } + + return [UIImage imageWithContentsOfFile:[self filePath]]; +} + +@end diff --git a/Signal/src/textsecure/Messages/TSAttachement.h b/Signal/src/textsecure/Messages/TSAttachement.h index d0a6f4d9c..7bffb037c 100644 --- a/Signal/src/textsecure/Messages/TSAttachement.h +++ b/Signal/src/textsecure/Messages/TSAttachement.h @@ -9,19 +9,18 @@ #import #import "TSYapDatabaseObject.h" -/** - * TSAttachements are stored by attachement id; - */ - @interface TSAttachement : TSYapDatabaseObject +- (NSNumber*)identifier; + +- (BOOL)isDownloaded; + +@property (nonatomic, readonly) NSData *encryptionKey; @property (nonatomic, readonly) NSString *contentType; -@property (nonatomic, readonly) NSURL *url; -@property (nonatomic, readonly) NSData *encryptionKey; -- (BOOL)expired; -- (NSString*)attachementId; +- (instancetype)initWithIdentifier:(NSString*)identifier + encryptionKey:(NSData*)encryptionKey + contentType:(NSString*)contentType; -- (instancetype)initWithAttachementId:(NSString*)attachementId url:(NSURL*)url encryptionKey:(NSData*)encryptionKey; @end diff --git a/Signal/src/textsecure/Messages/TSAttachement.m b/Signal/src/textsecure/Messages/TSAttachement.m index 85d28868c..7a861d1a5 100644 --- a/Signal/src/textsecure/Messages/TSAttachement.m +++ b/Signal/src/textsecure/Messages/TSAttachement.m @@ -1,3 +1,4 @@ + // // TSAttachement.m // TextSecureKit @@ -10,4 +11,31 @@ @implementation TSAttachement +- (instancetype)initWithIdentifier:(NSString*)identifier + encryptionKey:(NSData*)encryptionKey + contentType:(NSString*)contentType { + self = [super initWithUniqueId:identifier]; + + if (self) { + _encryptionKey = encryptionKey; + _contentType = contentType; + } + + return self; +} + ++ (NSString *)collection{ + return @"TSAttachements"; +} + +- (NSNumber*)identifier{ + NSNumberFormatter * f = [[NSNumberFormatter alloc] init]; + [f setNumberStyle:NSNumberFormatterDecimalStyle]; + return [f numberFromString:self.uniqueId]; +} + +- (BOOL)isDownloaded{ + return NO; +} + @end diff --git a/Signal/src/textsecure/Messages/TSMessage.h b/Signal/src/textsecure/Messages/TSMessage.h index 1fea71401..e414a8670 100644 --- a/Signal/src/textsecure/Messages/TSMessage.h +++ b/Signal/src/textsecure/Messages/TSMessage.h @@ -15,14 +15,16 @@ @interface TSMessage : TSInteraction -@property (nonatomic, readonly) NSArray *attachements;// contains TSAttachements -@property (nonatomic, readonly) NSString *body; +@property (nonatomic, readonly) NSMutableArray *attachements; +@property (nonatomic, readonly) NSString *body; - (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSThread*)thread messageBody:(NSString*)body attachements:(NSArray*)attachements; +- (void)addAttachements:(NSArray*)attachements; +- (void)addAttachement:(NSString*)attachement; - (BOOL)hasAttachements; @end diff --git a/Signal/src/textsecure/Messages/TSMessage.m b/Signal/src/textsecure/Messages/TSMessage.m index 6be65e64c..3b335be96 100644 --- a/Signal/src/textsecure/Messages/TSMessage.m +++ b/Signal/src/textsecure/Messages/TSMessage.m @@ -11,6 +11,20 @@ @implementation TSMessage +- (void)addAttachements:(NSArray*)attachements { + for (NSString *identifier in attachements) { + [self addAttachement:identifier]; + } +} + +- (void)addAttachement:(NSString*)attachement { + if (!_attachements) { + _attachements = [NSMutableArray array]; + } + + [self.attachements addObject:attachement]; +} + - (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSThread*)thread messageBody:(NSString*)body @@ -20,7 +34,7 @@ if (self) { _body = body; - _attachements = attachements; + _attachements = [attachements mutableCopy]; } return self; } @@ -30,7 +44,11 @@ } - (NSString *)description{ - return self.body; + if(self.attachements > 0){ + return @"Attachement"; + } else { + return self.body; + } } @end diff --git a/Signal/src/textsecure/Messages/TSMessagesManager+attachements.h b/Signal/src/textsecure/Messages/TSMessagesManager+attachements.h new file mode 100644 index 000000000..a12432014 --- /dev/null +++ b/Signal/src/textsecure/Messages/TSMessagesManager+attachements.h @@ -0,0 +1,17 @@ +// +// TSMessagesManager+attachements.h +// Signal +// +// Created by Frederic Jacobs on 17/12/14. +// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// + +#import "TSMessagesManager.h" +#import "TSAttachement.h" + +@interface TSMessagesManager (attachements) + +- (void)handleReceivedMediaMessage:(IncomingPushMessageSignal*)message withContent:(PushMessageContent*)content; +- (void)retrieveAttachment:(TSAttachement*)attachement; + +@end diff --git a/Signal/src/textsecure/Messages/TSMessagesManager+attachements.m b/Signal/src/textsecure/Messages/TSMessagesManager+attachements.m new file mode 100644 index 000000000..15f90fdaa --- /dev/null +++ b/Signal/src/textsecure/Messages/TSMessagesManager+attachements.m @@ -0,0 +1,116 @@ +// +// TSMessagesManager+attachements.m +// Signal +// +// Created by Frederic Jacobs on 17/12/14. +// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// + +#import "NSDate+millisecondTimeStamp.h" +#import + +#import "Cryptography.h" + +#import "TSConstants.h" +#import "TSMessagesManager+attachements.h" +#import "TSAttachementRequest.h" +#import "TSUploadAttachment.h" +#import "TSInfoMessage.h" +#import "TSAttachementPointer.h" +#import "TSNetworkManager.h" + +@interface TSMessagesManager () + +dispatch_queue_t attachementsQueue(void); + +@end + +dispatch_queue_t attachementsQueue() { + static dispatch_once_t queueCreationGuard; + static dispatch_queue_t queue; + dispatch_once(&queueCreationGuard, ^{ + queue = dispatch_queue_create("org.whispersystems.signal.attachements", NULL); + }); + return queue; +} + +@implementation TSMessagesManager (attachements) + +- (void)handleReceivedMediaMessage:(IncomingPushMessageSignal*)message withContent:(PushMessageContent*)content { + NSMutableArray *attachements = [NSMutableArray array]; + + [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + for (PushMessageContentAttachmentPointer *pointer in content.attachments) { + TSAttachementPointer *attachementPointer = [[TSAttachementPointer alloc] initWithIdentifier:pointer.id key:pointer.key contentType:pointer.contentType relay:message.relay]; + [attachementPointer saveWithTransaction:transaction]; + dispatch_async(attachementsQueue(), ^{ + [self retrieveAttachment:attachementPointer]; + }); + [attachements addObject:attachementPointer.uniqueId]; + } + }]; + + [self handleReceivedMessage:message withContent:content attachements:attachements]; +} + +- (void)retrieveAttachment:(TSAttachementPointer*)attachement { + + TSAttachementRequest *attachementRequest = [[TSAttachementRequest alloc] initWithId:[attachement identifier] + relay:attachement.relay]; + + [[TSNetworkManager sharedManager] queueAuthenticatedRequest:attachementRequest success:^(NSURLSessionDataTask *task, id responseObject) { + if ([responseObject isKindOfClass:[NSDictionary class]]) { + NSString *location = [(NSDictionary*)responseObject objectForKey:@"location"]; + NSData *data = [self downloadFromLocation:location]; + if (data) { + dispatch_async(attachementsQueue(), ^{ + [self decryptedAndSaveAttachement:attachement data:data]; + }); + } + + } + } failure:^(NSURLSessionDataTask *task, NSError *error) { + DDLogError(@"Failed task %@ error: %@", task.description, error.description); + }]; +} + +- (NSData*)downloadFromLocation:(NSString*)location { + __block NSData *data; + + AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; + manager.completionQueue = attachementsQueue(); + manager.requestSerializer = [AFHTTPRequestSerializer serializer]; + [manager.requestSerializer setValue:@"application/octet-stream" forHTTPHeaderField:@"Content-Type"]; + + manager.responseSerializer = [AFHTTPResponseSerializer serializer]; + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + [manager GET:location parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { + data = responseObject; + dispatch_semaphore_signal(sema); + } failure:^(AFHTTPRequestOperation *operation, NSError *error) { + DDLogError(@"Failed to retreive attachment with error: %@", error.description); + dispatch_semaphore_signal(sema); + }]; + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); + + return data; +} + +- (void)decryptedAndSaveAttachement:(TSAttachementPointer*)attachement data:(NSData*)cipherText { + NSData *plaintext = [Cryptography decryptAttachment:cipherText withKey:attachement.encryptionKey]; + + if (!plaintext) { + DDLogError(@"Failed to get attachement decrypted ..."); + } else { + TSAttachementStream *stream = [[TSAttachementStream alloc] initWithIdentifier:attachement.uniqueId + data:plaintext key:attachement.encryptionKey + contentType:attachement.contentType]; + [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [stream saveWithTransaction:transaction]; + }]; + NSLog(@"We got %@ of type %@", plaintext, attachement.contentType); + } + +} + +@end diff --git a/Signal/src/textsecure/Messages/TSMessagesManager.h b/Signal/src/textsecure/Messages/TSMessagesManager.h index d34243222..caab3efc2 100644 --- a/Signal/src/textsecure/Messages/TSMessagesManager.h +++ b/Signal/src/textsecure/Messages/TSMessagesManager.h @@ -8,6 +8,7 @@ #import #import "IncomingPushMessageSignal.pb.h" +#import "TSIncomingMessage.h" #import "TSOutgoingMessage.h" @interface TSMessagesManager : NSObject @@ -20,4 +21,6 @@ - (void)processException:(NSException*)exception outgoingMessage:(TSOutgoingMessage*)message; +- (void)handleReceivedMessage:(IncomingPushMessageSignal*)message withContent:(PushMessageContent*)content attachements:(NSArray*)attachements; + @end diff --git a/Signal/src/textsecure/Messages/TSMessagesManager.m b/Signal/src/textsecure/Messages/TSMessagesManager.m index 23bb39a0a..5950b5013 100644 --- a/Signal/src/textsecure/Messages/TSMessagesManager.m +++ b/Signal/src/textsecure/Messages/TSMessagesManager.m @@ -28,6 +28,7 @@ #import "TSStorageManager+PreKeyStore.h" #import "TSNetworkManager.h" #import "TSSubmitMessageRequest.h" +#import "TSMessagesManager+attachements.h" #import "NSData+messagePadding.h" @@ -184,13 +185,6 @@ } else if (content.attachments.count > 0) { DDLogVerbose(@"Received push media message (attachement) ..."); [self handleReceivedMediaMessage:incomingMessage withContent:content]; - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - TSInfoMessage *message = [[TSInfoMessage alloc] initWithTimestamp:incomingMessage.timestamp - inThread:[TSContactThread threadWithContactId:incomingMessage.source transaction:transaction] - messageType:TSInfoMessageTypeUnsupportedMessage]; - [message saveWithTransaction:transaction]; - }]; - } else { DDLogVerbose(@"Received push text message..."); [self handleReceivedTextMessage:incomingMessage withContent:content]; @@ -214,11 +208,11 @@ // TO DO } -- (void)handleReceivedMediaMessage:(IncomingPushMessageSignal*)message withContent:(PushMessageContent*)content{ - // TO DO +- (void)handleReceivedTextMessage:(IncomingPushMessageSignal*)message withContent:(PushMessageContent*)content{ + [self handleReceivedMessage:message withContent:content attachements:nil]; } -- (void)handleReceivedTextMessage:(IncomingPushMessageSignal*)message withContent:(PushMessageContent*)content{ +- (void)handleReceivedMessage:(IncomingPushMessageSignal*)message withContent:(PushMessageContent*)content attachements:(NSArray*)attachements { uint64_t timeStamp = message.timestamp; NSString *body = content.body; NSData *groupId = content.hasGroup?content.group.id:nil; @@ -229,12 +223,12 @@ if (groupId) { TSGroupThread *gThread = [TSGroupThread threadWithGroupId:groupId]; [gThread saveWithTransaction:transaction]; - incomingMessage = [[TSIncomingMessage alloc] initWithTimestamp:timeStamp inThread:gThread authorId:message.source messageBody:body attachements:nil]; + incomingMessage = [[TSIncomingMessage alloc] initWithTimestamp:timeStamp inThread:gThread authorId:message.source messageBody:body attachements:attachements]; thread = gThread; } else{ TSContactThread *cThread = [TSContactThread threadWithContactId:message.source transaction:transaction]; [cThread saveWithTransaction:transaction]; - incomingMessage = [[TSIncomingMessage alloc] initWithTimestamp:timeStamp inThread:cThread messageBody:body attachements:nil]; + incomingMessage = [[TSIncomingMessage alloc] initWithTimestamp:timeStamp inThread:cThread messageBody:body attachements:attachements]; thread = cThread; } [incomingMessage saveWithTransaction:transaction]; diff --git a/Signal/src/textsecure/Messages/TSOutgoingMessage.m b/Signal/src/textsecure/Messages/TSOutgoingMessage.m index 17956ca6b..89f574001 100644 --- a/Signal/src/textsecure/Messages/TSOutgoingMessage.m +++ b/Signal/src/textsecure/Messages/TSOutgoingMessage.m @@ -13,7 +13,7 @@ - (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread messageBody:(NSString *)body - attachements:(NSArray *)attachements + attachements:(NSMutableArray*)attachements { self = [super initWithTimestamp:timestamp inThread:thread messageBody:body attachements:attachements]; diff --git a/Signal/src/textsecure/Network/API/Requests/TSRequestAttachment.h b/Signal/src/textsecure/Network/API/Requests/TSAttachementRequest.h similarity index 62% rename from Signal/src/textsecure/Network/API/Requests/TSRequestAttachment.h rename to Signal/src/textsecure/Network/API/Requests/TSAttachementRequest.h index 6b7be1415..f03f09980 100644 --- a/Signal/src/textsecure/Network/API/Requests/TSRequestAttachment.h +++ b/Signal/src/textsecure/Network/API/Requests/TSAttachementRequest.h @@ -8,6 +8,8 @@ #import "TSRequest.h" -@interface TSRequestAttachment : TSRequest --(TSRequest*) initWithId:(NSNumber*) attachmentId; +@interface TSAttachementRequest : TSRequest + +-(TSRequest*) initWithId:(NSNumber*) attachmentId relay:(NSString*)relay; + @end diff --git a/Signal/src/textsecure/Network/API/Requests/TSAttachementRequest.m b/Signal/src/textsecure/Network/API/Requests/TSAttachementRequest.m new file mode 100644 index 000000000..0ff497d5e --- /dev/null +++ b/Signal/src/textsecure/Network/API/Requests/TSAttachementRequest.m @@ -0,0 +1,28 @@ +// +// TSRequestAttachment.m +// TextSecureiOS +// +// Created by Christine Corbett Moran on 12/1/13. +// Copyright (c) 2013 Open Whisper Systems. All rights reserved. +// + +#import "TSAttachementRequest.h" +#import "TSConstants.h" + +@implementation TSAttachementRequest + +-(TSRequest*) initWithId:(NSNumber*) attachmentId relay:(NSString*)relay { + + NSString *path = [NSString stringWithFormat:@"%@/%@", textSecureAttachmentsAPI, attachmentId]; + + if (relay && ![relay isEqualToString:@""]) { + path = [path stringByAppendingFormat:@"?relay=%@", relay]; + } + + self = [super initWithURL:[NSURL URLWithString:path]]; + + self.HTTPMethod = @"GET"; + return self; +} + +@end diff --git a/Signal/src/textsecure/Network/API/Requests/TSRequestAttachment.m b/Signal/src/textsecure/Network/API/Requests/TSRequestAttachment.m deleted file mode 100644 index acaf81f54..000000000 --- a/Signal/src/textsecure/Network/API/Requests/TSRequestAttachment.m +++ /dev/null @@ -1,20 +0,0 @@ -// -// TSRequestAttachment.m -// TextSecureiOS -// -// Created by Christine Corbett Moran on 12/1/13. -// Copyright (c) 2013 Open Whisper Systems. All rights reserved. -// - -#import "TSRequestAttachment.h" -#import "Constants.h" -@implementation TSRequestAttachment --(TSRequest*) initWithId:(NSNumber*) attachmentId { - - //self = [super initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@",textSecureAttachmentsAPI,attachmentId]]]; - self.HTTPMethod = @"GET"; - return self; -} - - -@end diff --git a/Signal/src/textsecure/Network/API/Requests/TSRequestAttachmentId.h b/Signal/src/textsecure/Network/API/Requests/TSRequestAttachmentId.h deleted file mode 100644 index 6e4236bdc..000000000 --- a/Signal/src/textsecure/Network/API/Requests/TSRequestAttachmentId.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// TSRequestAttachmentId.h -// TextSecureiOS -// -// Created by Christine Corbett Moran on 12/1/13. -// Copyright (c) 2013 Open Whisper Systems. All rights reserved. -// - -#import "TSRequest.h" - -@interface TSRequestAttachmentId : TSRequest - -@end diff --git a/Signal/src/textsecure/Network/API/Requests/TSRequestAttachmentId.m b/Signal/src/textsecure/Network/API/Requests/TSRequestAttachmentId.m deleted file mode 100644 index 0b745ca13..000000000 --- a/Signal/src/textsecure/Network/API/Requests/TSRequestAttachmentId.m +++ /dev/null @@ -1,20 +0,0 @@ -// -// TSRequestAttachmentId.m -// TextSecureiOS -// -// Created by Christine Corbett Moran on 12/1/13. -// Copyright (c) 2013 Open Whisper Systems. All rights reserved. -// - -#import "TSConstants.h" -#import "TSRequestAttachmentId.h" - -@implementation TSRequestAttachmentId --(TSRequest*) init { - - self = [super initWithURL:[NSURL URLWithString:textSecureAttachmentsAPI]]; - self.HTTPMethod = @"GET"; - return self; -} - -@end diff --git a/Signal/src/textsecure/Network/API/Requests/TSUploadAttachment.h b/Signal/src/textsecure/Network/API/Requests/TSUploadAttachment.h index a5498fa8b..83428b1f2 100644 --- a/Signal/src/textsecure/Network/API/Requests/TSUploadAttachment.h +++ b/Signal/src/textsecure/Network/API/Requests/TSUploadAttachment.h @@ -7,9 +7,10 @@ // #import "TSRequest.h" -@class TSAttachment; +#import "TSAttachementStream.h" + @interface TSUploadAttachment : TSRequest -@property(nonatomic,strong) TSAttachment* attachment; --(TSRequest*) initWithAttachment:(TSAttachment*) attachment ; + +-(TSRequest*) initWithAttachment:(TSAttachementStream*)attachment; @end diff --git a/Signal/src/textsecure/Network/API/Requests/TSUploadAttachment.m b/Signal/src/textsecure/Network/API/Requests/TSUploadAttachment.m index 02f9e3274..2faa7260e 100644 --- a/Signal/src/textsecure/Network/API/Requests/TSUploadAttachment.m +++ b/Signal/src/textsecure/Network/API/Requests/TSUploadAttachment.m @@ -7,11 +7,17 @@ // #import "TSUploadAttachment.h" +#import "TSAttachementStream.h" #import + +@interface TSUploadAttachment () +@property(nonatomic,strong) TSAttachement* attachment; +@end + @implementation TSUploadAttachment -//-(TSRequest*) initWithAttachment:(TSAttachment*) attachment{ -// +-(TSRequest*) initWithAttachment:(TSAttachementStream*)attachment{ + // self = [super initWithURL:attachment.attachmentURL]; // self.HTTPMethod = @"PUT"; // self.attachment = attachment; @@ -20,14 +26,7 @@ // [self setAllHTTPHeaderFields: @{@"Content-Type": @"application/octet-stream"}]; // // return self; -// -//} - - - - - - - + +} @end diff --git a/Signal/src/textsecure/Network/API/TSNetworkManager.m b/Signal/src/textsecure/Network/API/TSNetworkManager.m index 2773d5743..6254e3b3d 100644 --- a/Signal/src/textsecure/Network/API/TSNetworkManager.m +++ b/Signal/src/textsecure/Network/API/TSNetworkManager.m @@ -69,7 +69,7 @@ [self.operationManager.requestSerializer setAuthorizationHeaderFieldWithUsername:[TSAccountManager registeredNumber] password:[TSStorageManager serverAuthToken]]; - if ([request.HTTPMethod isEqualToString:@"GET"]) { + if ([request.HTTPMethod isEqualToString:@"GET"]) { [self.operationManager GET:[textSecureServerURL stringByAppendingString:request.URL.absoluteString] parameters:request.parameters success:success failure:failure]; } else if ([request.HTTPMethod isEqualToString:@"POST"]){ [self.operationManager POST:[textSecureServerURL stringByAppendingString:request.URL.absoluteString] parameters:request.parameters success:success failure:failure]; diff --git a/Signal/src/textsecure/Util/Cryptography.h b/Signal/src/textsecure/Util/Cryptography.h index a875a7675..89ec15879 100755 --- a/Signal/src/textsecure/Util/Cryptography.h +++ b/Signal/src/textsecure/Util/Cryptography.h @@ -12,7 +12,8 @@ typedef NS_ENUM(NSInteger, TSMACType) { TSHMACSHA1Truncated10Bytes = 1, - TSHMACSHA256Truncated10Bytes = 2 + TSHMACSHA256Truncated10Bytes = 2, + TSHMACSHA256AttachementType = 3 }; +(NSMutableData*) generateRandomBytes:(int)numberBytes; diff --git a/Signal/src/textsecure/Util/Cryptography.m b/Signal/src/textsecure/Util/Cryptography.m index f685a978f..6774ed141 100755 --- a/Signal/src/textsecure/Util/Cryptography.m +++ b/Signal/src/textsecure/Util/Cryptography.m @@ -14,6 +14,10 @@ #include "NSData+Base64.h" +#define HMAC256_KEY_LENGTH 32 +#define HMAC256_OUTPUT_LENGTH 32 +#define AES_CBC_IV_LENGTH 16 +#define AES_KEY_SIZE 32 @implementation Cryptography @@ -163,9 +167,10 @@ */ //verify hmac of version||encrypted data||iv NSMutableData *dataToHmac = [NSMutableData data ]; - if(version!=nil) { + if(version != nil) { [dataToHmac appendData:version]; } + [dataToHmac appendData:iv]; [dataToHmac appendData:dataToDecrypt]; @@ -173,20 +178,22 @@ if(hmacType == TSHMACSHA1Truncated10Bytes) { ourHmacData = [Cryptography truncatedSHA1HMAC:dataToHmac withHMACKey:hmacKey truncation:10]; - } - else if (hmacType == TSHMACSHA256Truncated10Bytes) { + } else if (hmacType == TSHMACSHA256Truncated10Bytes) { ourHmacData = [Cryptography truncatedSHA256HMAC:dataToHmac withHMACKey:hmacKey truncation:10]; + } else if (hmacType == TSHMACSHA256AttachementType){ + ourHmacData = [Cryptography truncatedSHA256HMAC:dataToHmac withHMACKey:hmacKey truncation:HMAC256_OUTPUT_LENGTH]; } if(hmac == nil || ![ourHmacData isEqualToData:hmac] ) { + DDLogError(@"Bad HMAC on decrypting payload"); return nil; } // decrypt size_t bufferSize = [dataToDecrypt length] + kCCBlockSizeAES128; void* buffer = malloc(bufferSize); - - size_t bytesDecrypted = 0; + + size_t bytesDecrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, [key bytes], [key length], [iv bytes], @@ -195,9 +202,11 @@ &bytesDecrypted); if (cryptStatus == kCCSuccess) { return [NSData dataWithBytesNoCopy:buffer length:bytesDecrypted]; + } else{ + DDLogError(@"Failed CBC decryption"); + free(buffer); } - - free(buffer); + return nil; } @@ -232,14 +241,20 @@ } +(NSData*) decryptAttachment:(NSData*) dataToDecrypt withKey:(NSData*) key { + if (([dataToDecrypt length] < AES_CBC_IV_LENGTH + HMAC256_OUTPUT_LENGTH) || ([key length] < AES_KEY_SIZE + HMAC256_KEY_LENGTH)) { + DDLogError(@"Message shorter than crypto overhead!"); + return nil; + } + // key: 32 byte AES key || 32 byte Hmac-SHA256 key. - NSData *encryptionKey = [key subdataWithRange:NSMakeRange(0, 32)]; - NSData *hmacKey = [key subdataWithRange:NSMakeRange(32, 32)]; + NSData *encryptionKey = [key subdataWithRange:NSMakeRange(0, AES_KEY_SIZE)]; + NSData *hmacKey = [key subdataWithRange:NSMakeRange(AES_KEY_SIZE, HMAC256_KEY_LENGTH)]; + // dataToDecrypt: IV || Ciphertext || truncated MAC(IV||Ciphertext) - NSData *iv = [dataToDecrypt subdataWithRange:NSMakeRange(0, 10)]; - NSData *encryptedAttachment = [dataToDecrypt subdataWithRange:NSMakeRange(10, [dataToDecrypt length]-10-10)]; - NSData *hmac = [dataToDecrypt subdataWithRange:NSMakeRange([dataToDecrypt length]-10, 10)]; - return [Cryptography decryptCBCMode:encryptedAttachment key:encryptionKey IV:iv version:nil HMACKey:hmacKey HMACType:TSHMACSHA256Truncated10Bytes matchingHMAC:hmac]; + NSData *iv = [dataToDecrypt subdataWithRange:NSMakeRange(0, AES_CBC_IV_LENGTH)]; + NSData *encryptedAttachment = [dataToDecrypt subdataWithRange:NSMakeRange(AES_CBC_IV_LENGTH, [dataToDecrypt length]-AES_CBC_IV_LENGTH-HMAC256_OUTPUT_LENGTH)]; + NSData *hmac = [dataToDecrypt subdataWithRange:NSMakeRange([dataToDecrypt length]-HMAC256_OUTPUT_LENGTH, HMAC256_OUTPUT_LENGTH)]; + return [Cryptography decryptCBCMode:encryptedAttachment key:encryptionKey IV:iv version:nil HMACKey:hmacKey HMACType:TSHMACSHA256AttachementType matchingHMAC:hmac]; } diff --git a/Signal/src/view controllers/MessagesViewController.m b/Signal/src/view controllers/MessagesViewController.m index 868e3d978..532e1f830 100644 --- a/Signal/src/view controllers/MessagesViewController.m +++ b/Signal/src/view controllers/MessagesViewController.m @@ -37,6 +37,7 @@ #import "TSErrorMessage.h" #import "TSIncomingMessage.h" #import "TSInteraction.h" +#import "TSAttachementAdapter.h" #import "TSMessagesManager+sendMessages.h" #import "NSDate+millisecondTimeStamp.h" @@ -288,7 +289,7 @@ typedef enum : NSUInteger { case TSErrorMessageAdapter: return [self loadErrorMessageCellForMessage:msg atIndexPath:indexPath]; break; - + default: NSLog(@"Something went wrong"); return nil; @@ -467,15 +468,15 @@ typedef enum : NSUInteger { BOOL isMediaMessage = [messageItem isMediaMessage]; if (isMediaMessage) { - id messageMedia = [messageItem media]; + TSAttachementAdapter * messageMedia = (TSAttachementAdapter*)[messageItem media]; - if ([messageMedia isKindOfClass:JSQPhotoMediaItem.class]) { + if ([messageMedia isImage]) { //is a photo - tappedImage = ((JSQPhotoMediaItem*)messageMedia).image ; + tappedImage = ((UIImageView*)[messageMedia mediaView]).image ; [self performSegueWithIdentifier:@"fullImage" sender:self]; - } else if ([messageMedia isKindOfClass:JSQVideoMediaItem.class]) { - //is a video + } else { + DDLogWarn(@"Currently unsupported"); } } diff --git a/Signal/src/view controllers/TSAttachementAdapter.h b/Signal/src/view controllers/TSAttachementAdapter.h new file mode 100644 index 000000000..ace958d7f --- /dev/null +++ b/Signal/src/view controllers/TSAttachementAdapter.h @@ -0,0 +1,19 @@ +// +// TSAttachementAdapter.h +// Signal +// +// Created by Frederic Jacobs on 17/12/14. +// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// + +#import +#import "TSAttachementStream.h" +#import + +@interface TSAttachementAdapter : JSQMediaItem + +- (instancetype)initWithAttachement:(TSAttachementStream*)attachement; + +- (BOOL)isImage; + +@end diff --git a/Signal/src/view controllers/TSAttachementAdapter.m b/Signal/src/view controllers/TSAttachementAdapter.m new file mode 100644 index 000000000..c61770811 --- /dev/null +++ b/Signal/src/view controllers/TSAttachementAdapter.m @@ -0,0 +1,74 @@ +// +// TSAttachementAdapter.m +// Signal +// +// Created by Frederic Jacobs on 17/12/14. +// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// + +#import "TSAttachementAdapter.h" + +#import "JSQMessagesMediaViewBubbleImageMasker.h" + +@interface TSAttachementAdapter () + +@property UIImage *image; + +@property (strong, nonatomic) UIImageView *cachedImageView; + +@property (assign, nonatomic, readonly) BOOL isImageAttachment; + +@end + +@implementation TSAttachementAdapter + +- (instancetype)initWithAttachement:(TSAttachementStream*)attachement{ + self = [super init]; + + if (self) { + _image = [UIImage imageWithCGImage:attachement.image.CGImage]; + _cachedImageView = nil; + _isImageAttachment = YES; + } + return self; +} + +- (void)dealloc +{ + _image = nil; + _cachedImageView = nil; +} + +- (void)setAppliesMediaViewMaskAsOutgoing:(BOOL)appliesMediaViewMaskAsOutgoing +{ + [super setAppliesMediaViewMaskAsOutgoing:appliesMediaViewMaskAsOutgoing]; + _cachedImageView = nil; +} + +#pragma mark - JSQMessageMediaData protocol + +- (UIView *)mediaView +{ + if (self.image == nil) { + return nil; + } + + if (self.cachedImageView == nil) { + CGSize size = [self mediaViewDisplaySize]; + UIImageView *imageView = [[UIImageView alloc] initWithImage:self.image]; + imageView.frame = CGRectMake(0.0f, 0.0f, size.width, size.height); + imageView.contentMode = UIViewContentModeScaleAspectFill; + imageView.clipsToBounds = YES; + [JSQMessagesMediaViewBubbleImageMasker applyBubbleImageMaskToMediaView:imageView isOutgoing:self.appliesMediaViewMaskAsOutgoing]; + self.cachedImageView = imageView; + } + + return self.cachedImageView; +} + +-(BOOL)isImage +{ + return _isImageAttachment; +} + +@end diff --git a/Signal/src/view controllers/TSMessageAdapter.m b/Signal/src/view controllers/TSMessageAdapter.m index c7b55d67b..c3d1e88d5 100644 --- a/Signal/src/view controllers/TSMessageAdapter.m +++ b/Signal/src/view controllers/TSMessageAdapter.m @@ -12,6 +12,9 @@ #import "TSCall.h" #import "TSInfoMessage.h" #import "TSErrorMessage.h" +#import "TSAttachement.h" +#import "TSAttachementStream.h" +#import "TSAttachementAdapter.h" @interface TSMessageAdapter () @@ -36,6 +39,10 @@ @property NSInteger outgoingMessageStatus; +// for MediaMessages + +@property JSQMediaItem *mediaItem; + // --- @property (nonatomic, copy) NSDate *messageDate; @@ -48,11 +55,11 @@ @implementation TSMessageAdapter -+ (instancetype)messageViewDataWithInteraction:(TSInteraction*)interaction inThread:(TSThread*)thread{ - ++ (id)messageViewDataWithInteraction:(TSInteraction*)interaction inThread:(TSThread*)thread{ + TSMessageAdapter *adapter = [[TSMessageAdapter alloc] init]; - adapter.messageDate = interaction.date; - adapter.identifier = (NSUInteger)interaction.uniqueId; + adapter.messageDate = interaction.date; + adapter.identifier = (NSUInteger)interaction.uniqueId; if ([thread isKindOfClass:[TSContactThread class]]) { adapter.thread = (TSContactThread*)thread; @@ -80,6 +87,23 @@ if ([interaction isKindOfClass:[TSIncomingMessage class]] || [interaction isKindOfClass:[TSOutgoingMessage class]]) { TSMessage *message = (TSMessage*)interaction; adapter.messageBody = message.body; + + if (message.attachements > 0) { + + + for (NSString *attachementID in message.attachements) { + TSAttachement *attachement = [TSAttachement fetchObjectWithUniqueID:attachementID]; + + if ([attachement isKindOfClass:[TSAttachementStream class]]) { + TSAttachementStream *stream = (TSAttachementStream*)attachement; + if ([stream isImage]) { + adapter.mediaItem = [[TSAttachementAdapter alloc] initWithAttachement:stream]; + adapter.mediaItem.appliesMediaViewMaskAsOutgoing = [interaction isKindOfClass:[TSOutgoingMessage class]]; + } + } + } + } + } else if ([interaction isKindOfClass:[TSCall class]]){ adapter.messageBody = @"Placeholder for TSCalls"; adapter.messageType = TSCallAdapter; @@ -123,7 +147,11 @@ } - (BOOL)isMediaMessage{ - return NO; + return _mediaItem?YES:NO; +} + +- (id)media{ + return _mediaItem; } - (NSString *)text{