mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-01-22 03:58:47 +00:00
Merge commit '24d097edbc174162662cc18ecffaa44b4d9bc46f'
# Conflicts: # MTProtoKit/MTSerialization.h
This commit is contained in:
@@ -69,6 +69,12 @@ MTInternalIdClass(MTHttpWorker)
|
||||
int32_t randomId = 0;
|
||||
arc4random_buf(&randomId, 4);
|
||||
|
||||
/*#ifdef DEBUG
|
||||
if (![address isIpv6]) {
|
||||
address = [[MTDatacenterAddress alloc] initWithIp:@"127.0.0.1" port:443 preferForMedia:address.preferForMedia restrictToTcp:address.restrictToTcp];
|
||||
}
|
||||
#endif*/
|
||||
|
||||
NSString *urlString = [[NSString alloc] initWithFormat:@"http://%@:%d/api%" PRIx32 "", address.ip, (int)address.port, randomId];
|
||||
|
||||
self = [super initWithBaseURL:[[NSURL alloc] initWithString:urlString]];
|
||||
|
||||
@@ -68,6 +68,8 @@ static inline int roundUpInput(int numToRound, int multiple)
|
||||
{
|
||||
if (MTLogEnabled()) {
|
||||
MTLog(@"***** Couldn't read int32");
|
||||
|
||||
@throw [[NSException alloc] initWithName:@"MTInputStreamException" reason:@"readInt32 end of stream" userInfo:@{}];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
@property (nonatomic, strong, readonly) NSData *iv;
|
||||
|
||||
+ (instancetype)messageEncryptionKeyForAuthKey:(NSData *)authKey messageKey:(NSData *)messageKey toClient:(bool)toClient;
|
||||
+ (instancetype)messageEncryptionKeyV2ForAuthKey:(NSData *)authKey messageKey:(NSData *)messageKey toClient:(bool)toClient;
|
||||
|
||||
- (instancetype)initWithKey:(NSData *)key iv:(NSData *)iv;
|
||||
|
||||
@end
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
NSAssert(messageKey != nil, @"message key should not be nil");
|
||||
#endif
|
||||
|
||||
#warning TODO more precise length check
|
||||
|
||||
if (authKey == nil || authKey.length == 0 || messageKey == nil || messageKey.length == 0)
|
||||
return nil;
|
||||
|
||||
@@ -77,6 +75,55 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (instancetype)messageEncryptionKeyV2ForAuthKey:(NSData *)authKey messageKey:(NSData *)messageKey toClient:(bool)toClient {
|
||||
#ifdef DEBUG
|
||||
NSAssert(authKey != nil, @"authKey should not be nil");
|
||||
NSAssert(messageKey != nil, @"message key should not be nil");
|
||||
#endif
|
||||
|
||||
if (authKey == nil || authKey.length == 0 || messageKey == nil || messageKey.length == 0)
|
||||
return nil;
|
||||
|
||||
/*
|
||||
sha256_a = SHA256 (msg_key + substr (auth_key, x, 36));
|
||||
|
||||
sha256_b = SHA256 (substr (auth_key, 40+x, 36) + msg_key);
|
||||
|
||||
aes_key = substr (sha256_a, 0, 8) + substr (sha256_b, 8, 16) + substr (sha256_a, 24, 8);
|
||||
aes_iv = substr (sha256_b, 0, 8) + substr (sha256_a, 8, 16) + substr (sha256_b, 24, 8);
|
||||
*/
|
||||
|
||||
int xValue = toClient ? 8 : 0;
|
||||
|
||||
NSMutableData *sha256_a_data = [[NSMutableData alloc] init];
|
||||
[sha256_a_data appendData:messageKey];
|
||||
[sha256_a_data appendBytes:authKey.bytes + xValue length:36];
|
||||
|
||||
NSData *sha256_a = MTSha256(sha256_a_data);
|
||||
|
||||
NSMutableData *sha256_b_data = [[NSMutableData alloc] init];
|
||||
[sha256_b_data appendBytes:authKey.bytes + 40 + xValue length:36];
|
||||
[sha256_b_data appendData:messageKey];
|
||||
|
||||
NSData *sha256_b = MTSha256(sha256_b_data);
|
||||
|
||||
NSMutableData *aesKey = [[NSMutableData alloc] init];
|
||||
[aesKey appendBytes:sha256_a.bytes + 0 length:8];
|
||||
[aesKey appendBytes:sha256_b.bytes + 8 length:16];
|
||||
[aesKey appendBytes:sha256_a.bytes + 24 length:8];
|
||||
|
||||
NSMutableData *aesIv = [[NSMutableData alloc] init];
|
||||
[aesIv appendBytes:sha256_b.bytes + 0 length:8];
|
||||
[aesIv appendBytes:sha256_a.bytes + 8 length:16];
|
||||
[aesIv appendBytes:sha256_b.bytes + 24 length:8];
|
||||
|
||||
MTMessageEncryptionKey *result = [[MTMessageEncryptionKey alloc] init];
|
||||
result->_key = [[NSData alloc] initWithData:aesKey];
|
||||
result->_iv = [[NSData alloc] initWithData:aesIv];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (instancetype)initWithKey:(NSData *)key iv:(NSData *)iv
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
@@ -55,6 +55,8 @@
|
||||
|
||||
#import "MTTime.h"
|
||||
|
||||
#define MTProtoV2 1
|
||||
|
||||
typedef enum {
|
||||
MTProtoStateAwaitingDatacenterScheme = 1,
|
||||
MTProtoStateAwaitingDatacenterAuthorization = 2,
|
||||
@@ -1148,21 +1150,25 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
|
||||
[decryptedOs writeInt32:(int32_t)messageData.length];
|
||||
[decryptedOs writeData:messageData];
|
||||
|
||||
uint8_t randomBytes[15];
|
||||
arc4random_buf(randomBytes, 15);
|
||||
for (int i = 0; ((int)messageData.length + i) % 16 != 0; i++)
|
||||
{
|
||||
[decryptedOs write:&randomBytes[i] maxLength:1];
|
||||
}
|
||||
NSData *decryptedData = [self paddedData:[decryptedOs currentBytes]];
|
||||
|
||||
NSData *decryptedData = [decryptedOs currentBytes];
|
||||
#if MTProtoV2
|
||||
int xValue = 0;
|
||||
NSMutableData *msgKeyLargeData = [[NSMutableData alloc] init];
|
||||
[msgKeyLargeData appendBytes:_authInfo.authKey.bytes + 88 + xValue length:32];
|
||||
[msgKeyLargeData appendData:decryptedData];
|
||||
|
||||
NSData *msgKeyLarge = MTSha256(msgKeyLargeData);
|
||||
NSData *messageKey = [msgKeyLarge subdataWithRange:NSMakeRange(8, 16)];
|
||||
MTMessageEncryptionKey *encryptionKey = [MTMessageEncryptionKey messageEncryptionKeyV2ForAuthKey:_authInfo.authKey messageKey:messageKey toClient:false];
|
||||
#else
|
||||
NSData *messageKeyFull = MTSubdataSha1(decryptedData, 0, 32 + messageData.length);
|
||||
NSData *messageKey = [[NSData alloc] initWithBytes:(((int8_t *)messageKeyFull.bytes) + messageKeyFull.length - 16) length:16];
|
||||
MTMessageEncryptionKey *encryptionKey = [MTMessageEncryptionKey messageEncryptionKeyForAuthKey:_authInfo.authKey messageKey:messageKey toClient:false];
|
||||
#endif
|
||||
|
||||
NSData *transactionData = nil;
|
||||
|
||||
MTMessageEncryptionKey *encryptionKey = [MTMessageEncryptionKey messageEncryptionKeyForAuthKey:_authInfo.authKey messageKey:messageKey toClient:false];
|
||||
if (encryptionKey != nil)
|
||||
{
|
||||
NSMutableData *encryptedData = [[NSMutableData alloc] initWithCapacity:14 + decryptedData.length];
|
||||
@@ -1263,27 +1269,32 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
|
||||
[decryptedOs writeInt32:(int32_t)containerData.length];
|
||||
[decryptedOs writeData:containerData];
|
||||
|
||||
uint8_t randomBytes[15];
|
||||
arc4random_buf(randomBytes, 15);
|
||||
for (int i = 0; ((int)containerData.length + i) % 16 != 0; i++)
|
||||
{
|
||||
[decryptedOs write:&randomBytes[i] maxLength:1];
|
||||
}
|
||||
NSData *decryptedData = [self paddedData:[decryptedOs currentBytes]];
|
||||
|
||||
NSData *decryptedData = [decryptedOs currentBytes];
|
||||
#if MTProtoV2
|
||||
int xValue = 0;
|
||||
NSMutableData *msgKeyLargeData = [[NSMutableData alloc] init];
|
||||
[msgKeyLargeData appendBytes:_authInfo.authKey.bytes + 88 + xValue length:32];
|
||||
[msgKeyLargeData appendData:decryptedData];
|
||||
|
||||
NSData *msgKeyLarge = MTSha256(msgKeyLargeData);
|
||||
NSData *messageKey = [msgKeyLarge subdataWithRange:NSMakeRange(8, 16)];
|
||||
MTMessageEncryptionKey *encryptionKey = [MTMessageEncryptionKey messageEncryptionKeyV2ForAuthKey:_authInfo.authKey messageKey:messageKey toClient:false];
|
||||
int32_t nQuickAckId = *((int32_t *)(msgKeyLarge.bytes));
|
||||
#else
|
||||
NSData *messageKeyFull = MTSubdataSha1(decryptedData, 0, 32 + containerData.length);
|
||||
NSData *messageKey = [[NSData alloc] initWithBytes:(((int8_t *)messageKeyFull.bytes) + messageKeyFull.length - 16) length:16];
|
||||
|
||||
MTMessageEncryptionKey *encryptionKey = [MTMessageEncryptionKey messageEncryptionKeyForAuthKey:_authInfo.authKey messageKey:messageKey toClient:false];
|
||||
int32_t nQuickAckId = *((int32_t *)(messageKeyFull.bytes));
|
||||
#endif
|
||||
|
||||
nQuickAckId = nQuickAckId & 0x7fffffff;
|
||||
if (quickAckId != NULL)
|
||||
*quickAckId = nQuickAckId;
|
||||
|
||||
MTMessageEncryptionKey *encryptionKey = [MTMessageEncryptionKey messageEncryptionKeyForAuthKey:_authInfo.authKey messageKey:messageKey toClient:false];
|
||||
if (encryptionKey != nil)
|
||||
{
|
||||
NSMutableData *encryptedData = [[NSMutableData alloc] initWithCapacity:14 + decryptedData.length];
|
||||
NSMutableData *encryptedData = [[NSMutableData alloc] init];
|
||||
[encryptedData appendData:decryptedData];
|
||||
MTAesEncryptInplace(encryptedData, encryptionKey.key, encryptionKey.iv);
|
||||
|
||||
@@ -1311,6 +1322,39 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
|
||||
return messageData;
|
||||
}
|
||||
|
||||
- (NSData *)paddedData:(NSData *)data {
|
||||
NSMutableData *padded = [[NSMutableData alloc] initWithData:data];
|
||||
uint8_t randomBytes[128];
|
||||
arc4random_buf(randomBytes, 128);
|
||||
#if MTProtoV2
|
||||
int take = 0;
|
||||
while (take < 12) {
|
||||
[padded appendBytes:randomBytes + take length:1];
|
||||
take++;
|
||||
}
|
||||
|
||||
while (padded.length % 16 != 0) {
|
||||
[padded appendBytes:randomBytes + take length:1];
|
||||
take++;
|
||||
}
|
||||
|
||||
int remainingCount = arc4random_uniform(72 + 1 - take);
|
||||
while (remainingCount % 16 != 0) {
|
||||
remainingCount--;
|
||||
}
|
||||
|
||||
for (int i = 0; i < remainingCount; i++) {
|
||||
[padded appendBytes:randomBytes + take length:1];
|
||||
take++;
|
||||
}
|
||||
#else
|
||||
for (int i = 0; ((int)data.length + i) % 16 != 0; i++) {
|
||||
[padded appendBytes:randomBytes + i length:1];
|
||||
}
|
||||
#endif
|
||||
return padded;
|
||||
}
|
||||
|
||||
- (NSData *)_dataForEncryptedMessage:(MTPreparedMessage *)preparedMessage sessionInfo:(MTSessionInfo *)sessionInfo quickAckId:(int32_t *)quickAckId
|
||||
{
|
||||
MTOutputStream *decryptedOs = [[MTOutputStream alloc] init];
|
||||
@@ -1323,15 +1367,18 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
|
||||
[decryptedOs writeInt32:(int32_t)preparedMessage.data.length];
|
||||
[decryptedOs writeData:preparedMessage.data];
|
||||
|
||||
uint8_t randomBytes[15];
|
||||
arc4random_buf(randomBytes, 15);
|
||||
for (int i = 0; ((int)preparedMessage.data.length + i) % 16 != 0; i++)
|
||||
{
|
||||
[decryptedOs write:&randomBytes[i] maxLength:1];
|
||||
}
|
||||
NSData *decryptedData = [self paddedData:[decryptedOs currentBytes]];
|
||||
|
||||
NSData *decryptedData = [decryptedOs currentBytes];
|
||||
#if MTProtoV2
|
||||
int xValue = 0;
|
||||
NSMutableData *msgKeyLargeData = [[NSMutableData alloc] init];
|
||||
[msgKeyLargeData appendBytes:_authInfo.authKey.bytes + 88 + xValue length:32];
|
||||
[msgKeyLargeData appendData:decryptedData];
|
||||
|
||||
NSData *msgKeyLarge = MTSha256(msgKeyLargeData);
|
||||
NSData *messageKey = [msgKeyLarge subdataWithRange:NSMakeRange(8, 16)];
|
||||
MTMessageEncryptionKey *encryptionKey = [MTMessageEncryptionKey messageEncryptionKeyV2ForAuthKey:_authInfo.authKey messageKey:messageKey toClient:false];
|
||||
#else
|
||||
NSData *messageKeyFull = MTSubdataSha1(decryptedData, 0, 32 + preparedMessage.data.length);
|
||||
NSData *messageKey = [[NSData alloc] initWithBytes:(((int8_t *)messageKeyFull.bytes) + messageKeyFull.length - 16) length:16];
|
||||
|
||||
@@ -1341,6 +1388,8 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
|
||||
*quickAckId = nQuickAckId;
|
||||
|
||||
MTMessageEncryptionKey *encryptionKey = [MTMessageEncryptionKey messageEncryptionKeyForAuthKey:_authInfo.authKey messageKey:messageKey toClient:false];
|
||||
#endif
|
||||
|
||||
if (encryptionKey != nil)
|
||||
{
|
||||
NSMutableData *encryptedData = [[NSMutableData alloc] initWithCapacity:14 + decryptedData.length];
|
||||
@@ -1441,7 +1490,11 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
|
||||
if (keyId != 0 && _authInfo != nil)
|
||||
{
|
||||
NSData *messageKey = [is readData:16];
|
||||
#if MTProtoV2
|
||||
MTMessageEncryptionKey *encryptionKey = [MTMessageEncryptionKey messageEncryptionKeyV2ForAuthKey:_authInfo.authKey messageKey:messageKey toClient:true];
|
||||
#else
|
||||
MTMessageEncryptionKey *encryptionKey = [MTMessageEncryptionKey messageEncryptionKeyForAuthKey:_authInfo.authKey messageKey:messageKey toClient:true];
|
||||
#endif
|
||||
|
||||
NSMutableData *encryptedMessageData = [is readMutableData:(data.length - 24)];
|
||||
while (encryptedMessageData.length % 16 != 0) {
|
||||
@@ -1687,7 +1740,13 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
|
||||
return nil;
|
||||
|
||||
NSData *embeddedMessageKey = [data subdataWithRange:NSMakeRange(8, 16)];
|
||||
|
||||
#if MTProtoV2
|
||||
MTMessageEncryptionKey *encryptionKey = [MTMessageEncryptionKey messageEncryptionKeyV2ForAuthKey:_authInfo.authKey messageKey:embeddedMessageKey toClient:true];
|
||||
#else
|
||||
MTMessageEncryptionKey *encryptionKey = [MTMessageEncryptionKey messageEncryptionKeyForAuthKey:_authInfo.authKey messageKey:embeddedMessageKey toClient:true];
|
||||
#endif
|
||||
|
||||
if (encryptionKey == nil)
|
||||
return nil;
|
||||
|
||||
@@ -1696,11 +1755,22 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
|
||||
int32_t messageDataLength = 0;
|
||||
[decryptedData getBytes:&messageDataLength range:NSMakeRange(28, 4)];
|
||||
|
||||
if (messageDataLength < 0 || messageDataLength < (int32_t)decryptedData.length - 32 - 16 || messageDataLength > (int32_t)decryptedData.length - 32)
|
||||
if (messageDataLength < 0 || messageDataLength > (int32_t)decryptedData.length)
|
||||
return nil;
|
||||
|
||||
#if MTProtoV2
|
||||
int xValue = 8;
|
||||
NSMutableData *msgKeyLargeData = [[NSMutableData alloc] init];
|
||||
[msgKeyLargeData appendBytes:_authInfo.authKey.bytes + 88 + xValue length:32];
|
||||
[msgKeyLargeData appendData:decryptedData];
|
||||
|
||||
NSData *msgKeyLarge = MTSha256(msgKeyLargeData);
|
||||
NSData *messageKey = [msgKeyLarge subdataWithRange:NSMakeRange(8, 16)];
|
||||
#else
|
||||
NSData *messageKeyFull = MTSubdataSha1(decryptedData, 0, 32 + messageDataLength);
|
||||
NSData *messageKey = [[NSData alloc] initWithBytes:(((int8_t *)messageKeyFull.bytes) + messageKeyFull.length - 16) length:16];
|
||||
#endif
|
||||
|
||||
if (![messageKey isEqualToData:embeddedMessageKey])
|
||||
return nil;
|
||||
|
||||
|
||||
@@ -102,7 +102,14 @@ static void init_ctr(struct ctr_state *state, const unsigned char *iv)
|
||||
{
|
||||
_internalId = [[MTInternalId(MTTcpConnection) alloc] init];
|
||||
|
||||
/*#ifdef DEBUG
|
||||
if (![address isIpv6]) {
|
||||
address = [[MTDatacenterAddress alloc] initWithIp:@"127.0.0.1" port:443 preferForMedia:address.preferForMedia restrictToTcp:address.restrictToTcp];
|
||||
}
|
||||
#endif*/
|
||||
|
||||
_address = address;
|
||||
|
||||
_interface = interface;
|
||||
|
||||
if (context.apiEnvironment.datacenterAddressOverrides[@(datacenterId)] != nil) {
|
||||
|
||||
@@ -515,6 +515,7 @@
|
||||
D0D225101B4D817B0085E26D /* MtProtoKitDynamic.h in Headers */ = {isa = PBXBuildFile; fileRef = D0D2250F1B4D817B0085E26D /* MtProtoKitDynamic.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D0D225161B4D817B0085E26D /* MtProtoKitDynamic.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D2250B1B4D817B0085E26D /* MtProtoKitDynamic.framework */; };
|
||||
D0D2251D1B4D817B0085E26D /* MtProtoKitDynamicTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D0D2251C1B4D817B0085E26D /* MtProtoKitDynamicTests.m */; };
|
||||
D0D2689E1D7A055400C422DA /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D0CD990F1D75C16100F41187 /* libcrypto.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -785,6 +786,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D0D2689E1D7A055400C422DA /* libcrypto.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -2453,6 +2455,7 @@
|
||||
);
|
||||
MACH_O_TYPE = staticlib;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_LDFLAGS = "-lz";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.telegram.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_MODULE_NAME = MtProtoKit;
|
||||
@@ -2627,6 +2630,7 @@
|
||||
);
|
||||
MACH_O_TYPE = staticlib;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_LDFLAGS = "-lz";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.telegram.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_MODULE_NAME = MtProtoKit;
|
||||
@@ -2679,6 +2683,7 @@
|
||||
);
|
||||
MACH_O_TYPE = staticlib;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_LDFLAGS = "-lz";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.telegram.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_MODULE_NAME = MtProtoKit;
|
||||
|
||||
Reference in New Issue
Block a user