Swiftgram/submodules/MtProtoKit/MTProtoKit/MTInternalMessageParser.m
Peter 373769682e Add 'submodules/MtProtoKit/' from commit '14ab734b977fd4f1686a2a13415f6a4c9b9fdd6d'
git-subtree-dir: submodules/MtProtoKit
git-subtree-mainline: 3b155750f5a4894ff3dedf1860a37e94e0ea9571
git-subtree-split: 14ab734b977fd4f1686a2a13415f6a4c9b9fdd6d
2019-06-11 18:55:34 +01:00

753 lines
28 KiB
Objective-C

#import "MTInternalMessageParser.h"
#import "MTBufferReader.h"
#import "MTResPqMessage.h"
#import "MTRpcResultMessage.h"
#import "MTRpcError.h"
#import "MTDropRpcResultMessage.h"
#import "MTServerDhParamsMessage.h"
#import "MTServerDhInnerDataMessage.h"
#import "MTSetClientDhParamsResponseMessage.h"
#import "MTMsgsAckMessage.h"
#import "MTMsgsStateReqMessage.h"
#import "MTMsgsStateInfoMessage.h"
#import "MTMsgDetailedInfoMessage.h"
#import "MTMsgAllInfoMessage.h"
#import "MTMessage.h"
#import "MTMsgResendReqMessage.h"
#import "MTBadMsgNotificationMessage.h"
#import "MTPingMessage.h"
#import "MTPongMessage.h"
#import "MTNewSessionCreatedMessage.h"
#import "MTDestroySessionResponseMessage.h"
#import "MTMsgContainerMessage.h"
#import "MTFutureSaltsMessage.h"
#import "MTLogging.h"
#import <zlib.h>
@implementation MTInternalMessageParser
+ (id)parseMessage:(NSData *)data
{
MTBufferReader *reader = [[MTBufferReader alloc] initWithData:data];
int32_t signature = 0;
if ([reader readInt32:&signature])
{
switch (signature)
{
case (int32_t)0x05162463:
{
NSMutableData *nonce = [[NSMutableData alloc] init];
[nonce setLength:16];
if (![reader readBytes:nonce.mutableBytes length:16])
return nil;
NSMutableData *serverNonce = [[NSMutableData alloc] init];
[serverNonce setLength:16];
if (![reader readBytes:serverNonce.mutableBytes length:16])
return nil;
NSData *pq = nil;
if (![reader readTLBytes:&pq])
return nil;
if (![reader readInt32:NULL])
return nil;
int32_t count = 0;
if (![reader readInt32:&count])
return nil;
NSMutableArray *serverPublicKeyFingerprints = [[NSMutableArray alloc] init];
for (int32_t i = 0; i < count; i++)
{
int64_t fingerprint = 0;
if (![reader readInt64:&fingerprint])
return nil;
[serverPublicKeyFingerprints addObject:@(fingerprint)];
}
return [[MTResPqMessage alloc] initWithNonce:nonce serverNonce:serverNonce pq:pq serverPublicKeyFingerprints:serverPublicKeyFingerprints];
}
case (int32_t)0x79cb045d:
{
NSMutableData *nonce = [[NSMutableData alloc] init];
[nonce setLength:16];
if (![reader readBytes:nonce.mutableBytes length:16])
return nil;
NSMutableData *serverNonce = [[NSMutableData alloc] init];
[serverNonce setLength:16];
if (![reader readBytes:serverNonce.mutableBytes length:16])
return nil;
NSMutableData *nextNonceHash = [[NSMutableData alloc] init];
[nextNonceHash setLength:16];
if (![reader readBytes:nextNonceHash.mutableBytes length:16])
return nil;
return [[MTServerDhParamsFailMessage alloc] initWithNonce:nonce serverNonce:serverNonce nextNonceHash:nextNonceHash];
}
case (int32_t)0xd0e8075c:
{
NSMutableData *nonce = [[NSMutableData alloc] init];
[nonce setLength:16];
if (![reader readBytes:nonce.mutableBytes length:16])
return nil;
NSMutableData *serverNonce = [[NSMutableData alloc] init];
[serverNonce setLength:16];
if (![reader readBytes:serverNonce.mutableBytes length:16])
return nil;
NSData *encryptedResponse = nil;
if (![reader readTLBytes:&encryptedResponse])
return nil;
return [[MTServerDhParamsOkMessage alloc] initWithNonce:nonce serverNonce:serverNonce encryptedResponse:encryptedResponse];
}
case (int32_t)0xb5890dba:
{
NSMutableData *nonce = [[NSMutableData alloc] init];
[nonce setLength:16];
if (![reader readBytes:nonce.mutableBytes length:16])
return nil;
NSMutableData *serverNonce = [[NSMutableData alloc] init];
[serverNonce setLength:16];
if (![reader readBytes:serverNonce.mutableBytes length:16])
return nil;
int32_t g = 0;
if (![reader readInt32:&g])
return nil;
NSData *dhPrime = nil;
if (![reader readTLBytes:&dhPrime])
return nil;
NSData *gA = nil;
if (![reader readTLBytes:&gA])
return nil;
int32_t serverTime = 0;
if (![reader readInt32:&serverTime])
return nil;
return [[MTServerDhInnerDataMessage alloc] initWithNonce:nonce serverNonce:serverNonce g:g dhPrime:dhPrime gA:gA serverTime:serverTime];
}
case (int32_t)0x3bcbf734:
{
NSMutableData *nonce = [[NSMutableData alloc] init];
[nonce setLength:16];
if (![reader readBytes:nonce.mutableBytes length:16])
return nil;
NSMutableData *serverNonce = [[NSMutableData alloc] init];
[serverNonce setLength:16];
if (![reader readBytes:serverNonce.mutableBytes length:16])
return nil;
NSMutableData *nextNonceHash1 = [[NSMutableData alloc] init];
[nextNonceHash1 setLength:16];
if (![reader readBytes:nextNonceHash1.mutableBytes length:16])
return nil;
return [[MTSetClientDhParamsResponseOkMessage alloc] initWithNonce:nonce serverNonce:serverNonce nextNonceHash1:nextNonceHash1];
}
case (int32_t)0x46dc1fb9:
{
NSMutableData *nonce = [[NSMutableData alloc] init];
[nonce setLength:16];
if (![reader readBytes:nonce.mutableBytes length:16])
return nil;
NSMutableData *serverNonce = [[NSMutableData alloc] init];
[serverNonce setLength:16];
if (![reader readBytes:serverNonce.mutableBytes length:16])
return nil;
NSMutableData *nextNonceHash2 = [[NSMutableData alloc] init];
[nextNonceHash2 setLength:16];
if (![reader readBytes:nextNonceHash2.mutableBytes length:16])
return nil;
return [[MTSetClientDhParamsResponseRetryMessage alloc] initWithNonce:nonce serverNonce:serverNonce nextNonceHash2:nextNonceHash2];
}
case (int32_t)0xa69dae02:
{
NSMutableData *nonce = [[NSMutableData alloc] init];
[nonce setLength:16];
if (![reader readBytes:nonce.mutableBytes length:16])
return nil;
NSMutableData *serverNonce = [[NSMutableData alloc] init];
[serverNonce setLength:16];
if (![reader readBytes:serverNonce.mutableBytes length:16])
return nil;
NSMutableData *nextNonceHash3 = [[NSMutableData alloc] init];
[nextNonceHash3 setLength:16];
if (![reader readBytes:nextNonceHash3.mutableBytes length:16])
return nil;
return [[MTSetClientDhParamsResponseFailMessage alloc] initWithNonce:nonce serverNonce:serverNonce nextNonceHash3:nextNonceHash3];
}
case (int32_t)0xf35c6d01:
{
int64_t requestMessageId = 0;
if (![reader readInt64:&requestMessageId])
return nil;
NSData *responseData = [reader readRest];
return [[MTRpcResultMessage alloc] initWithRequestMessageId:requestMessageId data:responseData];
}
case (int32_t)0x2144ca19:
{
int32_t errorCode = 0;
if (![reader readInt32:&errorCode])
return nil;
NSString *errorDescription = @"";
if (![reader readTLString:&errorDescription])
return nil;
return [[MTRpcError alloc] initWithErrorCode:errorCode errorDescription:errorDescription];
}
case (int32_t)0x5e2ad36e:
{
return [[MTDropRpcResultUnknownMessage alloc] init];
}
case (int32_t)0xcd78e586:
{
return [[MTDropRpcResultDroppedRunningMessage alloc] init];
}
case (int32_t)0xa43ad8b7:
{
int64_t messageId = 0;
if (![reader readInt64:&messageId])
return nil;
int32_t seqNo = 0;
if (![reader readInt32:&seqNo])
return nil;
int32_t size = 0;
if (![reader readInt32:&size])
return nil;
return [[MTDropRpcResultDroppedMessage alloc] initWithMessageId:messageId seqNo:seqNo size:size];
}
case (int32_t)0xda69fb52:
{
if (![reader readInt32:NULL])
return nil;
int32_t count = 0;
if (![reader readInt32:&count])
return nil;
NSMutableArray *messageIds = [[NSMutableArray alloc] init];
for (int32_t i = 0; i < count; i++)
{
int64_t messageId = 0;
if (![reader readInt64:&messageId])
return nil;
[messageIds addObject:@(messageId)];
}
return [[MTMsgsStateReqMessage alloc] initWithMessageIds:messageIds];
}
case (int32_t)0x04deb57d:
{
int64_t requestMessageId = 0;
if (![reader readInt64:&requestMessageId])
return nil;
NSData *info = nil;
if (![reader readTLBytes:&info])
return nil;
return [[MTMsgsStateInfoMessage alloc] initWithRequestMessageId:requestMessageId info:info];
}
case (int32_t)0x276d3ec6:
{
int64_t requestMessageId = 0;
if (![reader readInt64:&requestMessageId])
return nil;
int64_t responseMessageId = 0;
if (![reader readInt64:&responseMessageId])
return nil;
int32_t responseLength = 0;
if (![reader readInt32:&responseLength])
return nil;
int32_t status = 0;
if (![reader readInt32:&status])
return nil;
return [[MTMsgDetailedResponseInfoMessage alloc] initWithRequestMessageId:requestMessageId responseMessageId:responseMessageId responseLength:responseLength status:status];
}
case (int32_t)0x809db6df:
{
int64_t responseMessageId = 0;
if (![reader readInt64:&responseMessageId])
return nil;
int32_t responseLength = 0;
if (![reader readInt32:&responseLength])
return nil;
int32_t status = 0;
if (![reader readInt32:&status])
return nil;
return [[MTMsgDetailedInfoMessage alloc] initWithResponseMessageId:responseMessageId responseLength:responseLength status:status];
}
case (int32_t)0x8cc0d131:
{
if (![reader readInt32:NULL])
return nil;
int32_t count = 0;
if (![reader readInt32:&count])
return nil;
NSMutableArray *messageIds = [[NSMutableArray alloc] init];
for (int32_t i = 0; i < count; i++)
{
int64_t messageId = 0;
if (![reader readInt64:&messageId])
return nil;
[messageIds addObject:@(messageId)];
}
NSData *info = nil;
if (![reader readTLBytes:&info])
return nil;
return [[MTMsgAllInfoMessage alloc] initWithMessageIds:messageIds info:info];
}
case (int32_t)0xe06046b2:
{
int32_t messageSignature = 0;
if (![reader readInt32:&messageSignature] || messageSignature != (int32_t)0x5bb8e511)
return nil;
int64_t messageId = 0;
if (![reader readInt64:&messageId])
return nil;
int32_t seqNo = 0;
if (![reader readInt32:&seqNo])
return nil;
int32_t length = 0;
if (![reader readInt32:&length])
return nil;
NSData *data = [reader readRest];
if (data.length != (NSUInteger)length)
return nil;
return [[MTMessage alloc] initWithMessageId:messageId seqNo:seqNo data:data];
}
case (int32_t)0x7d861a08:
{
int32_t count = 0;
if (![reader readInt32:&count])
return nil;
NSMutableArray *messageIds = [[NSMutableArray alloc] init];
for (int32_t i = 0; i < count; i++)
{
int64_t messageId = 0;
if (![reader readInt64:&messageId])
return nil;
[messageIds addObject:@(messageId)];
}
return [[MTMsgResendReqMessage alloc] initWithMessageIds:messageIds];
}
case (int32_t)0xa7eff811:
{
int64_t badMessageId = 0;
if (![reader readInt64:&badMessageId])
return nil;
int32_t badMessageSeqNo = 0;
if (![reader readInt32:&badMessageSeqNo])
return nil;
int32_t errorCode = 0;
if (![reader readInt32:&errorCode])
return nil;
return [[MTBadMsgNotificationMessage alloc] initWithBadMessageId:badMessageId badMessageSeqNo:badMessageSeqNo errorCode:errorCode];
}
case (int32_t)0xedab447b:
{
int64_t badMessageId = 0;
if (![reader readInt64:&badMessageId])
return nil;
int32_t badMessageSeqNo = 0;
if (![reader readInt32:&badMessageSeqNo])
return nil;
int32_t errorCode = 0;
if (![reader readInt32:&errorCode])
return nil;
int64_t nextServerSalt = 0;
if (![reader readInt64:&nextServerSalt])
return nil;
return [[MTBadServerSaltNotificationMessage alloc] initWithBadMessageId:badMessageId badMessageSeqNo:badMessageSeqNo errorCode:errorCode nextServerSalt:nextServerSalt];
}
case (int32_t)0x62d6b459:
{
int32_t vectorSignature = 0;
if (![reader readInt32:&vectorSignature])
{
if (MTLogEnabled()) {
MTLog(@"[MTInternalMessageParser: msgs_ack can't read vectorSignature]");
}
return nil;
}
else if (vectorSignature != (int32_t)0x1cb5c415)
{
if (MTLogEnabled()) {
MTLog(@"[MTInternalMessageParser: msgs_ack invalid vectorSignature]");
}
return nil;
}
int32_t count = 0;
if (![reader readInt32:&count])
{
if (MTLogEnabled()) {
MTLog(@"[MTInternalMessageParser: msgs_ack can't read count]");
}
return nil;
}
NSMutableArray *messageIds = [[NSMutableArray alloc] init];
for (int32_t i = 0; i < count; i++)
{
int64_t messageId = 0;
if (![reader readInt64:&messageId])
{
if (MTLogEnabled()) {
MTLog(@"[MTInternalMessageParser: msgs_ack can't read messageId]");
}
return nil;
}
[messageIds addObject:@(messageId)];
}
return [[MTMsgsAckMessage alloc] initWithMessageIds:messageIds];
}
case (int32_t)0x7abe77ec:
{
int64_t pingId = 0;
if (![reader readInt64:&pingId])
{
if (MTLogEnabled()) {
MTLog(@"[MTInternalMessageParser: ping can't read pingId]");
}
return nil;
}
return [[MTPingMessage alloc] initWithPingId:pingId];
}
case (int32_t)0x347773c5:
{
int64_t messageId = 0;
if (![reader readInt64:&messageId])
{
if (MTLogEnabled()) {
MTLog(@"[MTInternalMessageParser: pong can't read messageId]");
}
return nil;
}
int64_t pingId = 0;
if (![reader readInt64:&pingId])
{
if (MTLogEnabled()) {
MTLog(@"[MTInternalMessageParser: pong can't read pingId]");
}
return nil;
}
return [[MTPongMessage alloc] initWithMessageId:messageId pingId:pingId];
}
case (int32_t)0x9ec20908:
{
int64_t firstMessageId = 0;
if (![reader readInt64:&firstMessageId])
{
if (MTLogEnabled()) {
MTLog(@"[MTInternalMessageParser: new_session_created can't read firstMessageId]");
}
return nil;
}
int64_t uniqueId = 0;
if (![reader readInt64:&uniqueId])
{
if (MTLogEnabled()) {
MTLog(@"[MTInternalMessageParser: new_session_created can't read uniqueId]");
}
return nil;
}
int64_t serverSalt = 0;
if (![reader readInt64:&serverSalt])
{
if (MTLogEnabled()) {
MTLog(@"[MTInternalMessageParser: new_session_created can't read serverSalt]");
}
return nil;
}
return [[MTNewSessionCreatedMessage alloc] initWithFirstMessageId:firstMessageId uniqueId:uniqueId serverSalt:serverSalt];
}
case (int32_t)0xe22045fc:
{
int64_t sessionId = 0;
if (![reader readInt64:&sessionId])
{
if (MTLogEnabled()) {
MTLog(@"[MTInternalMessageParser: destroy_session_ok can't read sessionId]");
}
return nil;
}
return [[MTDestroySessionResponseOkMessage alloc] initWithSessionId:sessionId];
}
case (int32_t)0x62d350c9:
{
int64_t sessionId = 0;
if (![reader readInt64:&sessionId])
{
if (MTLogEnabled()) {
MTLog(@"[MTInternalMessageParser: destroy_session_none can't read sessionId]");
}
return nil;
}
return [[MTDestroySessionResponseNoneMessage alloc] initWithSessionId:sessionId];
}
case (int32_t)0xfb95abcd:
{
NSData *responsesData = [reader readRest];
return [[MTDestroySessionMultipleResponseMessage alloc] initWithResponses:responsesData];
}
case (int32_t)0x73f1f8dc:
{
int32_t count = 0;
if (![reader readInt32:&count])
{
if (MTLogEnabled()) {
MTLog(@"[MTInternalMessageParser: msg_container can't read count]");
}
return nil;
}
NSMutableArray *messages = [[NSMutableArray alloc] init];
for (int32_t i = 0; i < count; i++)
{
int64_t messageId = 0;
if (![reader readInt64:&messageId])
{
if (MTLogEnabled()) {
MTLog(@"[MTInternalMessageParser: msg_container can't read messageId]");
}
return nil;
}
int32_t seqNo = 0;
if (![reader readInt32:&seqNo])
{
if (MTLogEnabled()) {
MTLog(@"[MTInternalMessageParser: msg_container can't read seqNo]");
}
return nil;
}
int32_t length = 0;
if (![reader readInt32:&length])
{
if (MTLogEnabled()) {
MTLog(@"[MTInternalMessageParser: msg_container can't read length]");
}
return nil;
}
if (length < 0 || length > 16 * 1024 * 1024)
{
if (MTLogEnabled()) {
MTLog(@"[MTInternalMessageParser: msg_container invalid length %d]", length);
}
return nil;
}
NSMutableData *messageData = [[NSMutableData alloc] init];
[messageData setLength:(NSUInteger)length];
if (![reader readBytes:messageData.mutableBytes length:(NSUInteger)length])
{
if (MTLogEnabled()) {
MTLog(@"[MTInternalMessageParser: msg_container can't read bytes]");
}
return nil;
}
[messages addObject:[[MTMessage alloc] initWithMessageId:messageId seqNo:seqNo data:messageData]];
}
return [[MTMsgContainerMessage alloc] initWithMessages:messages];
}
case (int32_t)0xae500895:
{
int64_t requestMessageId = 0;
if (![reader readInt64:&requestMessageId])
return nil;
int32_t now = 0;
if (![reader readInt32:&now])
return nil;
int32_t count = 0;
if (![reader readInt32:&count])
return nil;
NSMutableArray *salts = [[NSMutableArray alloc] init];
for (int32_t i = 0; i < count; i++)
{
int32_t validSince = 0;
if (![reader readInt32:&validSince])
return nil;
int32_t validUntil = 0;
if (![reader readInt32:&validUntil])
return nil;
int64_t salt = 0;
if (![reader readInt64:&salt])
return nil;
[salts addObject:[[MTFutureSalt alloc] initWithValidSince:validSince validUntil:validUntil salt:salt]];
}
return [[MTFutureSaltsMessage alloc] initWithRequestMessageId:requestMessageId now:now salts:salts];
}
default:
break;
}
}
return nil;
}
+ (NSData *)readBytes:(NSData *)data skippingLength:(NSUInteger)skipLength
{
NSUInteger offset = skipLength;
uint8_t tmp = 0;
[data getBytes:&tmp range:NSMakeRange(offset, 1)];
offset += 1;
int32_t length = tmp;
if (length == 254)
{
length = 0;
[data getBytes:((uint8_t *)&length) + 1 range:NSMakeRange(offset, 3)];
offset += 3;
length >>= 8;
}
return [data subdataWithRange:NSMakeRange(offset, length)];
}
+ (NSData *)decompressGZip:(NSData *)data
{
const int kMemoryChunkSize = 1024;
NSUInteger length = [data length];
int windowBits = 15 + 32; //Default + gzip header instead of zlib header
int retCode;
unsigned char output[kMemoryChunkSize];
uInt gotBack;
NSMutableData *result;
z_stream stream;
if ((length == 0) || (length > UINT_MAX)) //FIXME: Support 64 bit inputs
return nil;
bzero(&stream, sizeof(z_stream));
stream.avail_in = (uInt)length;
stream.next_in = (unsigned char*)[data bytes];
retCode = inflateInit2(&stream, windowBits);
if(retCode != Z_OK)
{
NSLog(@"%s: inflateInit2() failed with error %i", __PRETTY_FUNCTION__, retCode);
return nil;
}
result = [NSMutableData dataWithCapacity:(length * 4)];
do
{
stream.avail_out = kMemoryChunkSize;
stream.next_out = output;
retCode = inflate(&stream, Z_NO_FLUSH);
if ((retCode != Z_OK) && (retCode != Z_STREAM_END))
{
NSLog(@"%s: inflate() failed with error %i", __PRETTY_FUNCTION__, retCode);
inflateEnd(&stream);
return nil;
}
gotBack = kMemoryChunkSize - stream.avail_out;
if (gotBack > 0)
[result appendBytes:output length:gotBack];
} while( retCode == Z_OK);
inflateEnd(&stream);
return (retCode == Z_STREAM_END ? result : nil);
}
+ (NSData *)unwrapMessage:(NSData *)data
{
if (data.length < 4)
return data;
int32_t signature = 0;
[data getBytes:&signature length:4];
if (signature == (int32_t)0x3072cfa1)
{
NSData *packedData = [self readBytes:data skippingLength:4];
if (packedData != nil)
{
NSData *unpackedData = [self decompressGZip:packedData];
return unpackedData;
}
}
return data;
}
@end