123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673 |
- // _____ _
- // |_ _| |_ _ _ ___ ___ _ __ __ _
- // | | | ' \| '_/ -_) -_) ' \/ _` |_
- // |_| |_||_|_| \___\___|_|_|_\__,_(_)
- //
- // Threema iOS Client
- // Copyright (c) 2012-2020 Threema GmbH
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU Affero General Public License, version 3,
- // as published by the Free Software Foundation.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU Affero General Public License for more details.
- //
- // You should have received a copy of the GNU Affero General Public License
- // along with this program. If not, see <https://www.gnu.org/licenses/>.
- #import "MessageDecoder.h"
- #import "NaClCrypto.h"
- #import "ContactStore.h"
- #import "MyIdentityStore.h"
- #import "BoxedMessage.h"
- #import "ProtocolDefines.h"
- #import "BoxTextMessage.h"
- #import "BoxImageMessage.h"
- #import "BoxVideoMessage.h"
- #import "BoxLocationMessage.h"
- #import "BoxAudioMessage.h"
- #import "DeliveryReceiptMessage.h"
- #import "TypingIndicatorMessage.h"
- #import "GroupCreateMessage.h"
- #import "GroupRenameMessage.h"
- #import "GroupLeaveMessage.h"
- #import "GroupTextMessage.h"
- #import "GroupLocationMessage.h"
- #import "GroupImageMessage.h"
- #import "GroupVideoMessage.h"
- #import "GroupAudioMessage.h"
- #import "GroupSetPhotoMessage.h"
- #import "GroupRequestSyncMessage.h"
- #import "UnknownTypeMessage.h"
- #import "BoxBallotCreateMessage.h"
- #import "BoxBallotVoteMessage.h"
- #import "GroupBallotCreateMessage.h"
- #import "GroupBallotVoteMessage.h"
- #import "BoxFileMessage.h"
- #import "GroupFileMessage.h"
- #import "ContactSetPhotoMessage.h"
- #import "ContactDeletePhotoMessage.h"
- #import "ContactRequestPhotoMessage.h"
- #import "BoxVoIPCallOfferMessage.h"
- #import "BoxVoIPCallAnswerMessage.h"
- #import "BoxVoIPCallIceCandidatesMessage.h"
- #import "BoxVoIPCallHangupMessage.h"
- #import "BoxVoIPCallRingingMessage.h"
- #import "ValidationLogger.h"
- #import "GroupDeletePhotoMessage.h"
- #import "QuoteParser.h"
- #ifdef DEBUG
- static const DDLogLevel ddLogLevel = DDLogLevelVerbose;
- #else
- static const DDLogLevel ddLogLevel = DDLogLevelWarning;
- #endif
- @implementation MessageDecoder
- + (void)decodeFromBoxed:(BoxedMessage*)boxmsg isIncomming:(BOOL)isIncomming onCompletion:(void(^)(AbstractMessage *msg))onCompletion onError:(void(^)(NSError *err))onError {
- /* obtain sender's key, via API if necessary */
- [[ContactStore sharedContactStore] fetchPublicKeyForIdentity:boxmsg.fromIdentity onCompletion:^(NSData *publicKey) {
- AbstractMessage *msg = [MessageDecoder decodeFromBoxed:boxmsg isIncomming:isIncomming withPublicKey:publicKey];
- onCompletion(msg);
- } onError:^(NSError *error) {
- [[ValidationLogger sharedValidationLogger] logBoxedMessage:boxmsg isIncoming:isIncomming description:@"PublicKey from Threema-ID not found"];
- onError(error);
- }];
- }
- + (AbstractMessage*)decodeFromBoxed:(BoxedMessage*)boxmsg isIncomming:(BOOL)isIncomming withPublicKey:(NSData*)publicKey {
- if (![boxmsg.toIdentity isEqualToString:[MyIdentityStore sharedMyIdentityStore].identity]) {
- DDLogError(@"Message is not for my identity - cannot decode");
- [[ValidationLogger sharedValidationLogger] logBoxedMessage:boxmsg isIncoming:isIncomming description:@"Message is not for my identity - cannot decode"];
- return nil;
- }
-
- /* decrypt with our secret key */
- NSData *data = [[MyIdentityStore sharedMyIdentityStore] decryptData:boxmsg.box withNonce:boxmsg.nonce publicKey:publicKey];
- if (data == nil) {
- DDLogError(@"Decryption of message from %@ failed", boxmsg.fromIdentity);
- [[ValidationLogger sharedValidationLogger] logBoxedMessage:boxmsg isIncoming:isIncomming description:@"Decryption of message failed"];
- return nil;
- }
-
- if (data.length < 1) {
- DDLogError(@"Empty message received");
- [[ValidationLogger sharedValidationLogger] logBoxedMessage:boxmsg isIncoming:isIncomming description:@"Empty message received"];
- return nil;
- }
-
- /* remove padding */
- uint8_t padbytes = *((uint8_t*)data.bytes + data.length - 1);
- int realDataLength = (int)data.length - padbytes;
- if (realDataLength < 1) {
- DDLogError(@"Bad message padding");
- [[ValidationLogger sharedValidationLogger] logBoxedMessage:boxmsg isIncoming:isIncomming description:@"Bad message padding"];
- return nil;
- }
- DDLogVerbose(@"Effective data length is %d", realDataLength);
-
- uint8_t *type = (uint8_t*)data.bytes;
- AbstractMessage *msg = [MessageDecoder messageFromType: type data: data realDataLength: realDataLength fromIdentity: boxmsg.fromIdentity];
-
- if (msg != nil) {
- /* copy header attributes from boxed message */
- msg.fromIdentity = boxmsg.fromIdentity;
- msg.toIdentity = boxmsg.toIdentity;
- msg.messageId = boxmsg.messageId;
- msg.pushFromName = boxmsg.pushFromName;
- msg.date = boxmsg.date;
- msg.delivered = boxmsg.delivered;
- msg.deliveryDate = boxmsg.deliveryDate;
- msg.userAck = boxmsg.userAck;
- msg.sendUserAck = boxmsg.sendUserAck;
- msg.nonce = boxmsg.nonce;
- msg.flags = @(boxmsg.flags);
- }
-
- return msg;
- }
- + (AbstractMessage*)messageFromType:(uint8_t*)type data:(NSData *) data realDataLength: (int) realDataLength fromIdentity: (NSString*) fromIdentity{
- /* first byte of data is type */
- AbstractMessage *msg = nil;
- switch (*type) {
- case MSGTYPE_TEXT: {
- if (realDataLength < 1) {
- DDLogWarn(@"Wrong length %d for text message", realDataLength);
- break;
- }
- BoxTextMessage *textmsg = [[BoxTextMessage alloc] init];
- textmsg.text = [[NSString alloc] initWithData:[NSData dataWithBytes:(data.bytes + 1) length:(realDataLength - 1)] encoding:NSUTF8StringEncoding];
-
- NSString *remainingBody = nil;
- NSData *quotedMessageId = [QuoteParser parseQuoteV2FromMessage:textmsg.text remainingBody:&remainingBody];
-
- if (quotedMessageId != nil) {
- textmsg.text = remainingBody;
- textmsg.quotedMessageId = quotedMessageId;
- }
- msg = textmsg;
- break;
- }
- case MSGTYPE_IMAGE: {
- if (realDataLength != (1 + kBlobIdLen + sizeof(uint32_t) + kNonceLen)) {
- DDLogWarn(@"Wrong length %d for image message", realDataLength);
- break;
- }
- BoxImageMessage *imgmsg = [[BoxImageMessage alloc] init];
- imgmsg.blobId = [NSData dataWithBytes:(data.bytes + 1) length:kBlobIdLen];
- imgmsg.size = *((uint32_t*)(data.bytes + 1 + kBlobIdLen));
- imgmsg.imageNonce = [NSData dataWithBytes:(data.bytes + 1 + kBlobIdLen + sizeof(uint32_t)) length:kNonceLen];
- msg = imgmsg;
- break;
- }
- case MSGTYPE_VIDEO: {
- if (realDataLength != (1 + sizeof(uint16_t) + 2*(kBlobIdLen + sizeof(uint32_t)) + kBlobKeyLen)) {
- DDLogWarn(@"Wrong length %d for video message", realDataLength);
- break;
- }
- BoxVideoMessage *videomsg = [[BoxVideoMessage alloc] init];
- int i = 1;
- videomsg.duration = *((uint16_t*)(data.bytes + i)); i += sizeof(uint16_t);
- videomsg.videoBlobId = [NSData dataWithBytes:(data.bytes + i) length:kBlobIdLen]; i += kBlobIdLen;
- videomsg.videoSize = *((uint32_t*)(data.bytes + i)); i += sizeof(uint32_t);
- videomsg.thumbnailBlobId = [NSData dataWithBytes:(data.bytes + i) length:kBlobIdLen]; i += kBlobIdLen;
- videomsg.thumbnailSize = *((uint32_t*)(data.bytes + i)); i += sizeof(uint32_t);
- videomsg.encryptionKey = [NSData dataWithBytes:(data.bytes + i) length:kBlobKeyLen];
- msg = videomsg;
- break;
- }
- case MSGTYPE_LOCATION: {
- if (realDataLength < 4) {
- DDLogWarn(@"Wrong length %d for location message", realDataLength);
- break;
- }
-
- NSString *coordinateStr = [[NSString alloc] initWithData:[NSData dataWithBytes:(data.bytes + 1) length:(realDataLength - 1)] encoding:NSUTF8StringEncoding];
- if (coordinateStr == nil) {
- DDLogWarn(@"Bad coordinate string");
- break;
- }
-
- NSArray *lines = [coordinateStr componentsSeparatedByString:@"\n"];
- if (lines.count < 1) {
- DDLogWarn(@"Bad coordinate string");
- break;
- }
-
- NSArray *components = [lines[0] componentsSeparatedByString:@","];
- if (components.count < 2 || components.count > 3) {
- DDLogWarn(@"Bad coordinate format in location message");
- break;
- }
-
- BoxLocationMessage *locationmsg = [[BoxLocationMessage alloc] init];
- locationmsg.latitude = [components[0] doubleValue];
- locationmsg.longitude = [components[1] doubleValue];
-
- if (components.count == 3)
- locationmsg.accuracy = [components[2] doubleValue];
- else
- locationmsg.accuracy = 0;
-
- if (lines.count >= 2) {
- locationmsg.poiName = lines[1];
- if (lines.count >= 3)
- locationmsg.poiAddress = [lines[2] stringByReplacingOccurrencesOfString:@"\\n" withString:@"\n"];
- }
-
- if (locationmsg.latitude < -90.0 || locationmsg.latitude > 90.0 || locationmsg.longitude < -180.0 || locationmsg.longitude > 180.0) {
- DDLogWarn(@"Invalid coordinate values in location message");
- break;
- }
-
- msg = locationmsg;
- break;
- }
- case MSGTYPE_AUDIO: {
- if (realDataLength != (1 + sizeof(uint16_t) + kBlobIdLen + sizeof(uint32_t)) + kBlobKeyLen) {
- DDLogWarn(@"Wrong length %d for audio message", realDataLength);
- break;
- }
- BoxAudioMessage *audiomsg = [[BoxAudioMessage alloc] init];
- int i = 1;
- audiomsg.duration = *((uint16_t*)(data.bytes + i)); i += sizeof(uint16_t);
- audiomsg.audioBlobId = [NSData dataWithBytes:(data.bytes + i) length:kBlobIdLen]; i += kBlobIdLen;
- audiomsg.audioSize = *((uint32_t*)(data.bytes + i)); i += sizeof(uint32_t);
- audiomsg.encryptionKey = [NSData dataWithBytes:(data.bytes + i) length:kBlobKeyLen];
- msg = audiomsg;
- break;
- }
- case MSGTYPE_DELIVERY_RECEIPT: {
- if (realDataLength < kMessageIdLen + 2 || ((realDataLength - 2) % kMessageIdLen) != 0) {
- DDLogWarn(@"Wrong length %d for delivery receipt", realDataLength);
- break;
- }
- DeliveryReceiptMessage *receiptmsg = [[DeliveryReceiptMessage alloc] init];
- receiptmsg.receiptType = *((uint8_t*)(data.bytes + 1));
-
- int numMsgIds = ((realDataLength - 2) / kMessageIdLen);
- NSMutableArray *receiptMessageIds = [NSMutableArray arrayWithCapacity:numMsgIds];
- for (int i = 0; i < numMsgIds; i++) {
- NSData *receiptMessageId = [NSData dataWithBytes:(data.bytes + 2 + i*kMessageIdLen) length:kMessageIdLen];
- [receiptMessageIds addObject:receiptMessageId];
- }
-
- receiptmsg.receiptMessageIds = receiptMessageIds;
- msg = receiptmsg;
- break;
- }
- case MSGTYPE_TYPING_INDICATOR: {
- if (realDataLength != 2) {
- DDLogWarn(@"Wrong length %d for typing indicator", realDataLength);
- break;
- }
- TypingIndicatorMessage *typingmsg = [[TypingIndicatorMessage alloc] init];
- typingmsg.typing = *((uint8_t*)(data.bytes + 1)) ? YES : NO;
- msg = typingmsg;
- break;
- }
- case MSGTYPE_GROUP_CREATE: {
- if (realDataLength < (1 + kGroupIdLen) || ((realDataLength - 1 - kGroupIdLen) % kIdentityLen) != 0) {
- DDLogWarn(@"Wrong length %d for group create message", realDataLength);
- break;
- }
-
- GroupCreateMessage *groupcreatemsg = [[GroupCreateMessage alloc] init];
- groupcreatemsg.groupId = [NSData dataWithBytes:(data.bytes + 1) length:kGroupIdLen];
- int numMembers = ((realDataLength - kGroupIdLen - 1) / kIdentityLen);
- NSMutableArray *groupMembers = [NSMutableArray arrayWithCapacity:numMembers];
- for (int i = 0; i < numMembers; i++) {
- NSString *member = [[NSString alloc] initWithData:[NSData dataWithBytes:(data.bytes + 1 + kGroupIdLen + i*kIdentityLen) length:kIdentityLen] encoding:NSASCIIStringEncoding];
- if (member == nil) {
- DDLogWarn(@"Invalid group member ID");
- groupMembers = nil;
- break;
- }
- [groupMembers addObject:member];
- }
- if (groupMembers == nil)
- break;
- groupcreatemsg.groupMembers = groupMembers;
- groupcreatemsg.groupCreator = fromIdentity;
- msg = groupcreatemsg;
- break;
- }
- case MSGTYPE_GROUP_RENAME: {
- if (realDataLength < (1 + kGroupIdLen)) {
- DDLogWarn(@"Wrong length %d for group rename message", realDataLength);
- break;
- }
-
- GroupRenameMessage *renamemsg = [[GroupRenameMessage alloc] init];
- renamemsg.groupId = [NSData dataWithBytes:(data.bytes + 1) length:kGroupIdLen];
- renamemsg.name = [[NSString alloc] initWithData:[NSData dataWithBytes:(data.bytes + 1 + kGroupIdLen) length:(realDataLength - 1 - kGroupIdLen)] encoding:NSUTF8StringEncoding];
- renamemsg.groupCreator = fromIdentity;
- msg = renamemsg;
- break;
- }
- case MSGTYPE_GROUP_LEAVE: {
- if (realDataLength != (1 + kIdentityLen + kGroupIdLen)) {
- DDLogWarn(@"Wrong length %d for group leave message", realDataLength);
- break;
- }
-
- GroupLeaveMessage *groupleavemsg = [[GroupLeaveMessage alloc] init];
- groupleavemsg.groupCreator = [[NSString alloc] initWithData:[NSData dataWithBytes:(data.bytes + 1) length:kIdentityLen] encoding:NSASCIIStringEncoding];
- groupleavemsg.groupId = [NSData dataWithBytes:(data.bytes + 1 + kIdentityLen) length:kGroupIdLen];
- msg = groupleavemsg;
- break;
- }
- case MSGTYPE_GROUP_TEXT: {
- if (realDataLength < (1 + kIdentityLen + kGroupIdLen)) {
- DDLogWarn(@"Wrong length %d for group text message", realDataLength);
- break;
- }
- GroupTextMessage *textmsg = [[GroupTextMessage alloc] init];
- textmsg.groupCreator = [[NSString alloc] initWithData:[NSData dataWithBytes:(data.bytes + 1) length:kIdentityLen] encoding:NSASCIIStringEncoding];
- textmsg.groupId = [NSData dataWithBytes:(data.bytes + 1 + kIdentityLen) length:kGroupIdLen];
- textmsg.text = [[NSString alloc] initWithData:[NSData dataWithBytes:(data.bytes + 1 + kIdentityLen + kGroupIdLen) length:(realDataLength - 1 - kIdentityLen - kGroupIdLen)] encoding:NSUTF8StringEncoding];
-
- NSString *remainingBody = nil;
- NSData *quotedMessageId = [QuoteParser parseQuoteV2FromMessage:textmsg.text remainingBody:&remainingBody];
- if (quotedMessageId != nil) {
- textmsg.text = remainingBody;
- textmsg.quotedMessageId = quotedMessageId;
- }
-
- msg = textmsg;
- break;
- }
- case MSGTYPE_GROUP_LOCATION: {
- if (realDataLength < (kIdentityLen + kGroupIdLen + 4)) {
- DDLogWarn(@"Wrong length %d for group location message", realDataLength);
- break;
- }
-
- GroupLocationMessage *locationmsg = [[GroupLocationMessage alloc] init];
- locationmsg.groupCreator = [[NSString alloc] initWithData:[NSData dataWithBytes:(data.bytes + 1) length:kIdentityLen] encoding:NSASCIIStringEncoding];
- locationmsg.groupId = [NSData dataWithBytes:(data.bytes + 1 + kIdentityLen) length:kGroupIdLen];
-
- NSString *coordinateStr = [[NSString alloc] initWithData:[NSData dataWithBytes:(data.bytes + 1 + kIdentityLen + kGroupIdLen) length:(realDataLength - 1 - kIdentityLen - kGroupIdLen)] encoding:NSUTF8StringEncoding];
- if (coordinateStr == nil) {
- DDLogWarn(@"Bad coordinate string");
- break;
- }
-
- NSArray *lines = [coordinateStr componentsSeparatedByString:@"\n"];
- if (lines.count < 1) {
- DDLogWarn(@"Bad coordinate string");
- break;
- }
-
- NSArray *components = [lines[0] componentsSeparatedByString:@","];
- if (components.count < 2 || components.count > 3) {
- DDLogWarn(@"Bad coordinate format in location message");
- break;
- }
-
- locationmsg.latitude = [components[0] doubleValue];
- locationmsg.longitude = [components[1] doubleValue];
-
- if (components.count == 3)
- locationmsg.accuracy = [components[2] doubleValue];
- else
- locationmsg.accuracy = 0;
-
- if (lines.count >= 2) {
- locationmsg.poiName = lines[1];
- if (lines.count >= 3)
- locationmsg.poiAddress = [lines[2] stringByReplacingOccurrencesOfString:@"\\n" withString:@"\n"];
- }
-
- if (locationmsg.latitude < -90.0 || locationmsg.latitude > 90.0 || locationmsg.longitude < -180.0 || locationmsg.longitude > 180.0) {
- DDLogWarn(@"Invalid coordinate values in location message");
- break;
- }
-
- msg = locationmsg;
- break;
- }
- case MSGTYPE_GROUP_IMAGE: {
- if (realDataLength != (1 + kIdentityLen + kGroupIdLen + kBlobIdLen + sizeof(uint32_t) + kBlobKeyLen)) {
- DDLogWarn(@"Wrong length %d for group image message", realDataLength);
- break;
- }
- GroupImageMessage *imagemsg = [[GroupImageMessage alloc] init];
- int i = 1;
- imagemsg.groupCreator = [[NSString alloc] initWithData:[NSData dataWithBytes:(data.bytes + i) length:kIdentityLen] encoding:NSASCIIStringEncoding]; i += kIdentityLen;
- imagemsg.groupId = [NSData dataWithBytes:(data.bytes + i) length:kGroupIdLen]; i+= kGroupIdLen;
- imagemsg.blobId = [NSData dataWithBytes:(data.bytes + i) length:kBlobIdLen]; i += kBlobIdLen;
- imagemsg.size = *((uint32_t*)(data.bytes + i)); i += sizeof(uint32_t);
- imagemsg.encryptionKey = [NSData dataWithBytes:(data.bytes + i) length:kBlobKeyLen];
- msg = imagemsg;
- break;
- }
- case MSGTYPE_GROUP_VIDEO: {
- if (realDataLength != (1 + kIdentityLen + kGroupIdLen + sizeof(uint16_t) + 2*(kBlobIdLen + sizeof(uint32_t)) + kBlobKeyLen)) {
- DDLogWarn(@"Wrong length %d for group video message", realDataLength);
- break;
- }
- GroupVideoMessage *videomsg = [[GroupVideoMessage alloc] init];
- int i = 1;
- videomsg.groupCreator = [[NSString alloc] initWithData:[NSData dataWithBytes:(data.bytes + i) length:kIdentityLen] encoding:NSASCIIStringEncoding]; i += kIdentityLen;
- videomsg.groupId = [NSData dataWithBytes:(data.bytes + i) length:kGroupIdLen]; i+= kGroupIdLen;
- videomsg.duration = *((uint16_t*)(data.bytes + i)); i += sizeof(uint16_t);
- videomsg.videoBlobId = [NSData dataWithBytes:(data.bytes + i) length:kBlobIdLen]; i += kBlobIdLen;
- videomsg.videoSize = *((uint32_t*)(data.bytes + i)); i += sizeof(uint32_t);
- videomsg.thumbnailBlobId = [NSData dataWithBytes:(data.bytes + i) length:kBlobIdLen]; i += kBlobIdLen;
- videomsg.thumbnailSize = *((uint32_t*)(data.bytes + i)); i += sizeof(uint32_t);
- videomsg.encryptionKey = [NSData dataWithBytes:(data.bytes + i) length:kBlobKeyLen];
- msg = videomsg;
- break;
- }
- case MSGTYPE_GROUP_AUDIO: {
- if (realDataLength != (1 + kIdentityLen + kGroupIdLen + sizeof(uint16_t) + kBlobIdLen + sizeof(uint32_t)) + kBlobKeyLen) {
- DDLogWarn(@"Wrong length %d for group audio message", realDataLength);
- break;
- }
- GroupAudioMessage *audiomsg = [[GroupAudioMessage alloc] init];
- int i = 1;
- audiomsg.groupCreator = [[NSString alloc] initWithData:[NSData dataWithBytes:(data.bytes + i) length:kIdentityLen] encoding:NSASCIIStringEncoding]; i += kIdentityLen;
- audiomsg.groupId = [NSData dataWithBytes:(data.bytes + i) length:kGroupIdLen]; i+= kGroupIdLen;
- audiomsg.duration = *((uint16_t*)(data.bytes + i)); i += sizeof(uint16_t);
- audiomsg.audioBlobId = [NSData dataWithBytes:(data.bytes + i) length:kBlobIdLen]; i += kBlobIdLen;
- audiomsg.audioSize = *((uint32_t*)(data.bytes + i)); i += sizeof(uint32_t);
- audiomsg.encryptionKey = [NSData dataWithBytes:(data.bytes + i) length:kBlobKeyLen];
- msg = audiomsg;
- break;
- }
- case MSGTYPE_GROUP_SET_PHOTO: {
- if (realDataLength != (1 + kGroupIdLen + kBlobIdLen + sizeof(uint32_t) + kBlobKeyLen)) {
- DDLogWarn(@"Wrong length %d for group set photo message", realDataLength);
- break;
- }
-
- GroupSetPhotoMessage *setphotomsg = [[GroupSetPhotoMessage alloc] init];
- int i = 1;
- setphotomsg.groupId = [NSData dataWithBytes:(data.bytes + i) length:kGroupIdLen]; i+= kGroupIdLen;
- setphotomsg.blobId = [NSData dataWithBytes:(data.bytes + i) length:kBlobIdLen]; i += kBlobIdLen;
- setphotomsg.size = *((uint32_t*)(data.bytes + i)); i += sizeof(uint32_t);
- setphotomsg.encryptionKey = [NSData dataWithBytes:(data.bytes + i) length:kBlobKeyLen];
- setphotomsg.groupCreator = fromIdentity;
- msg = setphotomsg;
- break;
- }
- case MSGTYPE_GROUP_REQUEST_SYNC: {
- if (realDataLength != (1 + kGroupIdLen)) {
- DDLogWarn(@"Wrong length %d for group request sync message", realDataLength);
- break;
- }
-
- GroupRequestSyncMessage *groupsyncmsg = [[GroupRequestSyncMessage alloc] init];
- groupsyncmsg.groupId = [NSData dataWithBytes:(data.bytes + 1) length:kGroupIdLen];
- msg = groupsyncmsg;
- break;
- }
- case MSGTYPE_BALLOT_CREATE: {
- if (realDataLength < (1 + kBallotIdLen)) {
- DDLogWarn(@"Wrong length %d for ballot create message", realDataLength);
- break;
- }
- int i = 1;
- BoxBallotCreateMessage *ballotCreateMsg = [[BoxBallotCreateMessage alloc] init];
- ballotCreateMsg.ballotId = [NSData dataWithBytes:(data.bytes + i) length:kBallotIdLen];
- i+= kBallotIdLen;
- ballotCreateMsg.jsonData = [NSData dataWithBytes:(data.bytes + i) length:(realDataLength - i)];
- msg = ballotCreateMsg;
- break;
- }
- case MSGTYPE_BALLOT_VOTE: {
- if (realDataLength < (1 + kIdentityLen + kIdentityLen + kBallotIdLen)) {
- DDLogWarn(@"Wrong length %d for ballot vote message", realDataLength);
- break;
- }
-
- int i = 1;
- BoxBallotVoteMessage *ballotVoteMsg = [[BoxBallotVoteMessage alloc] init];
- ballotVoteMsg.ballotCreator = [[NSString alloc] initWithData:[NSData dataWithBytes:(data.bytes + i) length:kIdentityLen] encoding:NSASCIIStringEncoding];
- i+= kIdentityLen;
- ballotVoteMsg.ballotId = [NSData dataWithBytes:(data.bytes + i) length:kBallotIdLen];
- i+= kBallotIdLen;
- ballotVoteMsg.jsonChoiceData = [NSData dataWithBytes:(data.bytes + i) length:(realDataLength - i)];
- msg = ballotVoteMsg;
- break;
- }
- case MSGTYPE_GROUP_BALLOT_CREATE: {
- if (realDataLength < (1 + kIdentityLen + kGroupIdLen + kBallotIdLen)) {
- DDLogWarn(@"Wrong length %d for group ballot create message", realDataLength);
- break;
- }
-
- int i = 1;
- GroupBallotCreateMessage *ballotCreateMsg = [[GroupBallotCreateMessage alloc] init];
- ballotCreateMsg.groupCreator = [[NSString alloc] initWithData:[NSData dataWithBytes:(data.bytes + i) length:kIdentityLen] encoding:NSASCIIStringEncoding];
- i+= kIdentityLen;
- ballotCreateMsg.groupId = [NSData dataWithBytes:(data.bytes + i) length:kGroupIdLen];
- i+= kGroupIdLen;
- ballotCreateMsg.ballotId = [NSData dataWithBytes:(data.bytes + i) length:kBallotIdLen];
- i+= kBallotIdLen;
- ballotCreateMsg.jsonData = [NSData dataWithBytes:(data.bytes + i) length:(realDataLength - i)];
- msg = ballotCreateMsg;
- break;
- }
- case MSGTYPE_GROUP_BALLOT_VOTE: {
- if (realDataLength < (1 + kIdentityLen + kGroupIdLen + kIdentityLen + kBallotIdLen)) {
- DDLogWarn(@"Wrong length %d for group ballot vote message", realDataLength);
- break;
- }
-
- int i = 1;
- GroupBallotVoteMessage *ballotVoteMsg = [[GroupBallotVoteMessage alloc] init];
- ballotVoteMsg.groupCreator = [[NSString alloc] initWithData:[NSData dataWithBytes:(data.bytes + i) length:kIdentityLen] encoding:NSASCIIStringEncoding];
- i+= kIdentityLen;
- ballotVoteMsg.groupId = [NSData dataWithBytes:(data.bytes + i) length:kGroupIdLen];
- i+= kGroupIdLen;
- ballotVoteMsg.ballotCreator = [[NSString alloc] initWithData:[NSData dataWithBytes:(data.bytes + i) length:kIdentityLen] encoding:NSASCIIStringEncoding];
- i+= kIdentityLen;
- ballotVoteMsg.ballotId = [NSData dataWithBytes:(data.bytes + i) length:kBallotIdLen];
- i+= kBallotIdLen;
- ballotVoteMsg.jsonChoiceData = [NSData dataWithBytes:(data.bytes + i) length:(realDataLength - i)];
- msg = ballotVoteMsg;
- break;
- }
- case MSGTYPE_GROUP_DELETE_PHOTO: {
- if (realDataLength != (1 + kGroupIdLen)) {
- DDLogWarn(@"Wrong length %d for group delete photo message", realDataLength);
- break;
- }
-
- GroupDeletePhotoMessage *deletephotomsg = [[GroupDeletePhotoMessage alloc] init];
- deletephotomsg.groupId = [NSData dataWithBytes:(data.bytes + 1) length:kGroupIdLen];
- deletephotomsg.groupCreator = fromIdentity;
- msg = deletephotomsg;
- break;
- }
- case MSGTYPE_FILE: {
- if (realDataLength < 1) {
- DDLogWarn(@"Wrong length %d for file message", realDataLength);
- break;
- }
-
- int i = 1;
- BoxFileMessage *fileMessage = [[BoxFileMessage alloc] init];
- fileMessage.jsonData = [NSData dataWithBytes:(data.bytes + i) length:(realDataLength - i)];
- msg = fileMessage;
- break;
- }
- case MSGTYPE_GROUP_FILE: {
- if (realDataLength < (1 + kIdentityLen + kGroupIdLen)) {
- DDLogWarn(@"Wrong length %d for group file message", realDataLength);
- break;
- }
-
- int i = 1;
- GroupFileMessage *fileMessage = [[GroupFileMessage alloc] init];
- fileMessage.groupCreator = [[NSString alloc] initWithData:[NSData dataWithBytes:(data.bytes + i) length:kIdentityLen] encoding:NSASCIIStringEncoding];
- i+= kIdentityLen;
- fileMessage.groupId = [NSData dataWithBytes:(data.bytes + i) length:kGroupIdLen];
- i+= kGroupIdLen;
- fileMessage.jsonData = [NSData dataWithBytes:(data.bytes + i) length:(realDataLength - i)];
- msg = fileMessage;
- break;
- }
- case MSGTYPE_CONTACT_SET_PHOTO: {
- if (realDataLength != (1 + kBlobIdLen + sizeof(uint32_t) + kBlobKeyLen)) {
- DDLogWarn(@"Wrong length %d for contact set photo message", realDataLength);
- break;
- }
-
- ContactSetPhotoMessage *setphotomsg = [[ContactSetPhotoMessage alloc] init];
- int i = 1;
- setphotomsg.blobId = [NSData dataWithBytes:(data.bytes + i) length:kBlobIdLen]; i += kBlobIdLen;
- setphotomsg.size = *((uint32_t*)(data.bytes + i)); i += sizeof(uint32_t);
- setphotomsg.encryptionKey = [NSData dataWithBytes:(data.bytes + i) length:kBlobKeyLen];
- msg = setphotomsg;
- break;
- }
- case MSGTYPE_CONTACT_DELETE_PHOTO: {
- if (realDataLength != 1) {
- DDLogWarn(@"Wrong length %d for contact delete photo message", realDataLength);
- break;
- }
-
- ContactDeletePhotoMessage *deletephotomsg = [[ContactDeletePhotoMessage alloc] init];
- msg = deletephotomsg;
- break;
- }
- case MSGTYPE_CONTACT_REQUEST_PHOTO: {
- if (realDataLength != 1) {
- DDLogWarn(@"Wrong length %d for contact request photo message", realDataLength);
- break;
- }
-
- ContactRequestPhotoMessage *deletephotomsg = [[ContactRequestPhotoMessage alloc] init];
- msg = deletephotomsg;
- break;
- }
- case MSGTYPE_VOIP_CALL_OFFER: {
- if (realDataLength < 1) {
- DDLogWarn(@"Wrong length %d for call offer message", realDataLength);
- break;
- }
-
- int i = 1;
- BoxVoIPCallOfferMessage *offerMessage = [[BoxVoIPCallOfferMessage alloc] init];
- offerMessage.jsonData = [NSData dataWithBytes:(data.bytes + i) length:(realDataLength - i)];
- msg = offerMessage;
- break;
- }
- case MSGTYPE_VOIP_CALL_ANSWER: {
- if (realDataLength < 1) {
- DDLogWarn(@"Wrong length %d for call answer message", realDataLength);
- break;
- }
-
- int i = 1;
- BoxVoIPCallAnswerMessage *answerMessage = [[BoxVoIPCallAnswerMessage alloc] init];
- answerMessage.jsonData = [NSData dataWithBytes:(data.bytes + i) length:(realDataLength - i)];
- msg = answerMessage;
- break;
- }
- case MSGTYPE_VOIP_CALL_ICECANDIDATE: {
- if (realDataLength < 1) {
- DDLogWarn(@"Wrong length %d for call ice candidate message", realDataLength);
- break;
- }
-
- int i = 1;
- BoxVoIPCallIceCandidatesMessage *iceCandidateMessage = [[BoxVoIPCallIceCandidatesMessage alloc] init];
- iceCandidateMessage.jsonData = [NSData dataWithBytes:(data.bytes + i) length:(realDataLength - i)];
- msg = iceCandidateMessage;
- break;
- }
- case MSGTYPE_VOIP_CALL_HANGUP: {
- int i = 1;
- BoxVoIPCallHangupMessage *hangupMessage = [[BoxVoIPCallHangupMessage alloc] init];
- hangupMessage.jsonData = [NSData dataWithBytes:(data.bytes + i) length:(realDataLength - i)];
- msg = hangupMessage;
- break;
- }
- case MSGTYPE_VOIP_CALL_RINGING: {
- int i = 1;
- BoxVoIPCallRingingMessage *ringingMessage = [[BoxVoIPCallRingingMessage alloc] init];
- ringingMessage.jsonData = [NSData dataWithBytes:(data.bytes + i) length:(realDataLength - i)];
- msg = ringingMessage;
- break;
- }
- default:
- DDLogWarn(@"Unsupported message type %d", *type);
- msg = [[UnknownTypeMessage alloc] init];
- break;
- }
-
- return msg;
- }
- @end
|