Merge commit '24d097edbc174162662cc18ecffaa44b4d9bc46f'

# Conflicts:
#	MTProtoKit/MTSerialization.h
This commit is contained in:
Peter
2016-09-05 23:46:22 +03:00
7 changed files with 167 additions and 28 deletions

View File

@@ -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]];

View File

@@ -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:@{}];
}
}

View File

@@ -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

View File

@@ -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];

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;