mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Support new padding scheme
This commit is contained in:
parent
3cff0fe015
commit
e0abfd0f66
@ -379,14 +379,14 @@ static int32_t fixedTimeDifferenceValue = 0;
|
||||
NSDictionary *datacenterAuthInfoById = [keychain objectForKey:@"datacenterAuthInfoById" group:@"persistent"];
|
||||
if (datacenterAuthInfoById != nil) {
|
||||
_datacenterAuthInfoById = [[NSMutableDictionary alloc] initWithDictionary:datacenterAuthInfoById];
|
||||
/*#if DEBUG
|
||||
#if DEBUG
|
||||
NSArray<NSNumber *> *keys = [_datacenterAuthInfoById allKeys];
|
||||
for (NSNumber *key in keys) {
|
||||
if (parseAuthInfoMapKeyInteger(key).selector != MTDatacenterAuthInfoSelectorPersistent) {
|
||||
[_datacenterAuthInfoById removeObjectForKey:key];
|
||||
}
|
||||
}
|
||||
#endif*/
|
||||
#endif
|
||||
}
|
||||
|
||||
NSDictionary *datacenterPublicKeysById = [keychain objectForKey:@"datacenterPublicKeysById" group:@"ephemeral"];
|
||||
|
@ -13,6 +13,7 @@
|
||||
#import <MtProtoKit/MTDatacenterSaltInfo.h>
|
||||
#import "MTBuffer.h"
|
||||
#import <MtProtoKit/MTEncryption.h>
|
||||
#import <CommonCrypto/CommonCrypto.h>
|
||||
|
||||
#import "MTInternalMessageParser.h"
|
||||
#import "MTServerDhInnerDataMessage.h"
|
||||
@ -20,99 +21,133 @@
|
||||
#import "MTServerDhParamsMessage.h"
|
||||
#import "MTSetClientDhParamsResponseMessage.h"
|
||||
|
||||
static NSArray *defaultPublicKeys() {
|
||||
static NSArray *serverPublicKeys = nil;
|
||||
@interface MTDatacenterAuthPublicKey : NSObject
|
||||
|
||||
@property (nonatomic, strong, readonly) NSString *publicKey;
|
||||
@property (nonatomic, readonly) bool usesModernPaddingScheme;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MTDatacenterAuthPublicKey
|
||||
|
||||
- (instancetype)initWithPublicKey:(NSString *)publicKey usesModernPaddingScheme:(bool)usesModernPaddingScheme {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
_publicKey = publicKey;
|
||||
_usesModernPaddingScheme = usesModernPaddingScheme;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (uint64_t)fingerprintWithEncryptionProvider:(id<EncryptionProvider>)encryptionProvider {
|
||||
return MTRsaFingerprint(encryptionProvider, _publicKey);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static NSArray<MTDatacenterAuthPublicKey *> *defaultPublicKeys() {
|
||||
static NSArray<MTDatacenterAuthPublicKey *> *serverPublicKeys = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^
|
||||
{
|
||||
serverPublicKeys = [[NSArray alloc] initWithObjects:
|
||||
[[NSDictionary alloc] initWithObjectsAndKeys:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAxq7aeLAqJR20tkQQMfRn+ocfrtMlJsQ2Uksfs7Xcoo77jAid0bRt\n"
|
||||
"ksiVmT2HEIJUlRxfABoPBV8wY9zRTUMaMA654pUX41mhyVN+XoerGxFvrs9dF1Ru\n"
|
||||
"vCHbI02dM2ppPvyytvvMoefRoL5BTcpAihFgm5xCaakgsJ/tH5oVl74CdhQw8J5L\n"
|
||||
"xI/K++KJBUyZ26Uba1632cOiq05JBUW0Z2vWIOk4BLysk7+U9z+SxynKiZR3/xdi\n"
|
||||
"XvFKk01R3BHV+GUKM2RYazpS/P8v7eyKhAbKxOdRcFpHLlVwfjyM1VlDQrEZxsMp\n"
|
||||
"NTLYXb6Sce1Uov0YtNx5wEowlREH1WOTlwIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----", @"key", [[NSNumber alloc] initWithUnsignedLongLong:0x9a996a1db11c729bUL], @"fingerprint", nil],
|
||||
[[NSDictionary alloc] initWithObjectsAndKeys:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAsQZnSWVZNfClk29RcDTJQ76n8zZaiTGuUsi8sUhW8AS4PSbPKDm+\n"
|
||||
"DyJgdHDWdIF3HBzl7DHeFrILuqTs0vfS7Pa2NW8nUBwiaYQmPtwEa4n7bTmBVGsB\n"
|
||||
"1700/tz8wQWOLUlL2nMv+BPlDhxq4kmJCyJfgrIrHlX8sGPcPA4Y6Rwo0MSqYn3s\n"
|
||||
"g1Pu5gOKlaT9HKmE6wn5Sut6IiBjWozrRQ6n5h2RXNtO7O2qCDqjgB2vBxhV7B+z\n"
|
||||
"hRbLbCmW0tYMDsvPpX5M8fsO05svN+lKtCAuz1leFns8piZpptpSCFn7bWxiA9/f\n"
|
||||
"x5x17D7pfah3Sy2pA+NDXyzSlGcKdaUmwQIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----", @"key", [[NSNumber alloc] initWithUnsignedLongLong:0xb05b2a6f70cdea78UL], @"fingerprint", nil],
|
||||
[[NSDictionary alloc] initWithObjectsAndKeys:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAwVACPi9w23mF3tBkdZz+zwrzKOaaQdr01vAbU4E1pvkfj4sqDsm6\n"
|
||||
"lyDONS789sVoD/xCS9Y0hkkC3gtL1tSfTlgCMOOul9lcixlEKzwKENj1Yz/s7daS\n"
|
||||
"an9tqw3bfUV/nqgbhGX81v/+7RFAEd+RwFnK7a+XYl9sluzHRyVVaTTveB2GazTw\n"
|
||||
"Efzk2DWgkBluml8OREmvfraX3bkHZJTKX4EQSjBbbdJ2ZXIsRrYOXfaA+xayEGB+\n"
|
||||
"8hdlLmAjbCVfaigxX0CDqWeR1yFL9kwd9P0NsZRPsmoqVwMbMu7mStFai6aIhc3n\n"
|
||||
"Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----", @"key", [[NSNumber alloc] initWithUnsignedLongLong:0xc3b42b026ce86b21UL], @"fingerprint", nil],
|
||||
[[NSDictionary alloc] initWithObjectsAndKeys:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAwqjFW0pi4reKGbkc9pK83Eunwj/k0G8ZTioMMPbZmW99GivMibwa\n"
|
||||
"xDM9RDWabEMyUtGoQC2ZcDeLWRK3W8jMP6dnEKAlvLkDLfC4fXYHzFO5KHEqF06i\n"
|
||||
"qAqBdmI1iBGdQv/OQCBcbXIWCGDY2AsiqLhlGQfPOI7/vvKc188rTriocgUtoTUc\n"
|
||||
"/n/sIUzkgwTqRyvWYynWARWzQg0I9olLBBC2q5RQJJlnYXZwyTL3y9tdb7zOHkks\n"
|
||||
"WV9IMQmZmyZh/N7sMbGWQpt4NMchGpPGeJ2e5gHBjDnlIf2p1yZOYeUYrdbwcS0t\n"
|
||||
"UiggS4UeE8TzIuXFQxw7fzEIlmhIaq3FnwIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----", @"key", [[NSNumber alloc] initWithUnsignedLongLong:0x71e025b6c76033e3UL], @"fingerprint", nil],
|
||||
[[NSDictionary alloc] initWithObjectsAndKeys:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAruw2yP/BCcsJliRoW5eBVBVle9dtjJw+OYED160Wybum9SXtBBLX\n"
|
||||
"riwt4rROd9csv0t0OHCaTmRqBcQ0J8fxhN6/cpR1GWgOZRUAiQxoMnlt0R93LCX/\n"
|
||||
"j1dnVa/gVbCjdSxpbrfY2g2L4frzjJvdl84Kd9ORYjDEAyFnEA7dD556OptgLQQ2\n"
|
||||
"e2iVNq8NZLYTzLp5YpOdO1doK+ttrltggTCy5SrKeLoCPPbOgGsdxJxyz5KKcZnS\n"
|
||||
"Lj16yE5HvJQn0CNpRdENvRUXe6tBP78O39oJ8BTHp9oIjd6XWXAsp2CvK45Ol8wF\n"
|
||||
"XGF710w9lwCGNbmNxNYhtIkdqfsEcwR5JwIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----", @"key", [[NSNumber alloc] initWithUnsignedLongLong:0xbc35f3509f7b7a5UL], @"fingerprint", nil],
|
||||
[[NSDictionary alloc] initWithObjectsAndKeys:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAvfLHfYH2r9R70w8prHblWt/nDkh+XkgpflqQVcnAfSuTtO05lNPs\n"
|
||||
"pQmL8Y2XjVT4t8cT6xAkdgfmmvnvRPOOKPi0OfJXoRVylFzAQG/j83u5K3kRLbae\n"
|
||||
"7fLccVhKZhY46lvsueI1hQdLgNV9n1cQ3TDS2pQOCtovG4eDl9wacrXOJTG2990V\n"
|
||||
"jgnIKNA0UMoP+KF03qzryqIt3oTvZq03DyWdGK+AZjgBLaDKSnC6qD2cFY81UryR\n"
|
||||
"WOab8zKkWAnhw2kFpcqhI0jdV5QaSCExvnsjVaX0Y1N0870931/5Jb9ICe4nweZ9\n"
|
||||
"kSDF/gip3kWLG0o8XQpChDfyvsqB9OLV/wIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----", @"key", [[NSNumber alloc] initWithUnsignedLongLong:0x15ae5fa8b5529542UL], @"fingerprint", nil],
|
||||
[[NSDictionary alloc] initWithObjectsAndKeys:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAs/ditzm+mPND6xkhzwFIz6J/968CtkcSE/7Z2qAJiXbmZ3UDJPGr\n"
|
||||
"zqTDHkO30R8VeRM/Kz2f4nR05GIFiITl4bEjvpy7xqRDspJcCFIOcyXm8abVDhF+\n"
|
||||
"th6knSU0yLtNKuQVP6voMrnt9MV1X92LGZQLgdHZbPQz0Z5qIpaKhdyA8DEvWWvS\n"
|
||||
"Uwwc+yi1/gGaybwlzZwqXYoPOhwMebzKUk0xW14htcJrRrq+PXXQbRzTMynseCoP\n"
|
||||
"Ioke0dtCodbA3qQxQovE16q9zz4Otv2k4j63cz53J+mhkVWAeWxVGI0lltJmWtEY\n"
|
||||
"K6er8VqqWot3nqmWMXogrgRLggv/NbbooQIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----", @"key", [[NSNumber alloc] initWithUnsignedLongLong:0xaeae98e13cd7f94fUL], @"fingerprint", nil],
|
||||
[[NSDictionary alloc] initWithObjectsAndKeys:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAvmpxVY7ld/8DAjz6F6q05shjg8/4p6047bn6/m8yPy1RBsvIyvuD\n"
|
||||
"uGnP/RzPEhzXQ9UJ5Ynmh2XJZgHoE9xbnfxL5BXHplJhMtADXKM9bWB11PU1Eioc\n"
|
||||
"3+AXBB8QiNFBn2XI5UkO5hPhbb9mJpjA9Uhw8EdfqJP8QetVsI/xrCEbwEXe0xvi\n"
|
||||
"fRLJbY08/Gp66KpQvy7g8w7VB8wlgePexW3pT13Ap6vuC+mQuJPyiHvSxjEKHgqe\n"
|
||||
"Pji9NP3tJUFQjcECqcm0yV7/2d0t/pbCm+ZH1sadZspQCEPPrtbkQBlvHb4OLiIW\n"
|
||||
"PGHKSMeRFvp3IWcmdJqXahxLCUS1Eh6MAQIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----", @"key", [[NSNumber alloc] initWithUnsignedLongLong:0x5a181b2235057d98UL], @"fingerprint", nil],
|
||||
[[NSDictionary alloc] initWithObjectsAndKeys:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAr4v4wxMDXIaMOh8bayF/NyoYdpcysn5EbjTIOZC0RkgzsRj3SGlu\n"
|
||||
"52QSz+ysO41dQAjpFLgxPVJoOlxXokaOq827IfW0bGCm0doT5hxtedu9UCQKbE8j\n"
|
||||
"lDOk+kWMXHPZFJKWRgKgTu9hcB3y3Vk+JFfLpq3d5ZB48B4bcwrRQnzkx5GhWOFX\n"
|
||||
"x73ZgjO93eoQ2b/lDyXxK4B4IS+hZhjzezPZTI5upTRbs5ljlApsddsHrKk6jJNj\n"
|
||||
"8Ygs/ps8e6ct82jLXbnndC9s8HjEvDvBPH9IPjv5JUlmHMBFZ5vFQIfbpo0u0+1P\n"
|
||||
"n6bkEi5o7/ifoyVv2pAZTRwppTz0EuXD8QIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----", @"key", [[NSNumber alloc] initWithUnsignedLongLong:0x9692106da14b9f02UL], @"fingerprint", nil],
|
||||
nil];
|
||||
dispatch_once(&onceToken, ^{
|
||||
serverPublicKeys = @[
|
||||
[[MTDatacenterAuthPublicKey alloc] initWithPublicKey:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAxq7aeLAqJR20tkQQMfRn+ocfrtMlJsQ2Uksfs7Xcoo77jAid0bRt\n"
|
||||
"ksiVmT2HEIJUlRxfABoPBV8wY9zRTUMaMA654pUX41mhyVN+XoerGxFvrs9dF1Ru\n"
|
||||
"vCHbI02dM2ppPvyytvvMoefRoL5BTcpAihFgm5xCaakgsJ/tH5oVl74CdhQw8J5L\n"
|
||||
"xI/K++KJBUyZ26Uba1632cOiq05JBUW0Z2vWIOk4BLysk7+U9z+SxynKiZR3/xdi\n"
|
||||
"XvFKk01R3BHV+GUKM2RYazpS/P8v7eyKhAbKxOdRcFpHLlVwfjyM1VlDQrEZxsMp\n"
|
||||
"NTLYXb6Sce1Uov0YtNx5wEowlREH1WOTlwIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----" usesModernPaddingScheme:false],
|
||||
[[MTDatacenterAuthPublicKey alloc] initWithPublicKey:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAsQZnSWVZNfClk29RcDTJQ76n8zZaiTGuUsi8sUhW8AS4PSbPKDm+\n"
|
||||
"DyJgdHDWdIF3HBzl7DHeFrILuqTs0vfS7Pa2NW8nUBwiaYQmPtwEa4n7bTmBVGsB\n"
|
||||
"1700/tz8wQWOLUlL2nMv+BPlDhxq4kmJCyJfgrIrHlX8sGPcPA4Y6Rwo0MSqYn3s\n"
|
||||
"g1Pu5gOKlaT9HKmE6wn5Sut6IiBjWozrRQ6n5h2RXNtO7O2qCDqjgB2vBxhV7B+z\n"
|
||||
"hRbLbCmW0tYMDsvPpX5M8fsO05svN+lKtCAuz1leFns8piZpptpSCFn7bWxiA9/f\n"
|
||||
"x5x17D7pfah3Sy2pA+NDXyzSlGcKdaUmwQIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----" usesModernPaddingScheme:false],
|
||||
[[MTDatacenterAuthPublicKey alloc] initWithPublicKey:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAwVACPi9w23mF3tBkdZz+zwrzKOaaQdr01vAbU4E1pvkfj4sqDsm6\n"
|
||||
"lyDONS789sVoD/xCS9Y0hkkC3gtL1tSfTlgCMOOul9lcixlEKzwKENj1Yz/s7daS\n"
|
||||
"an9tqw3bfUV/nqgbhGX81v/+7RFAEd+RwFnK7a+XYl9sluzHRyVVaTTveB2GazTw\n"
|
||||
"Efzk2DWgkBluml8OREmvfraX3bkHZJTKX4EQSjBbbdJ2ZXIsRrYOXfaA+xayEGB+\n"
|
||||
"8hdlLmAjbCVfaigxX0CDqWeR1yFL9kwd9P0NsZRPsmoqVwMbMu7mStFai6aIhc3n\n"
|
||||
"Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----" usesModernPaddingScheme:false],
|
||||
[[MTDatacenterAuthPublicKey alloc] initWithPublicKey:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAwqjFW0pi4reKGbkc9pK83Eunwj/k0G8ZTioMMPbZmW99GivMibwa\n"
|
||||
"xDM9RDWabEMyUtGoQC2ZcDeLWRK3W8jMP6dnEKAlvLkDLfC4fXYHzFO5KHEqF06i\n"
|
||||
"qAqBdmI1iBGdQv/OQCBcbXIWCGDY2AsiqLhlGQfPOI7/vvKc188rTriocgUtoTUc\n"
|
||||
"/n/sIUzkgwTqRyvWYynWARWzQg0I9olLBBC2q5RQJJlnYXZwyTL3y9tdb7zOHkks\n"
|
||||
"WV9IMQmZmyZh/N7sMbGWQpt4NMchGpPGeJ2e5gHBjDnlIf2p1yZOYeUYrdbwcS0t\n"
|
||||
"UiggS4UeE8TzIuXFQxw7fzEIlmhIaq3FnwIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----" usesModernPaddingScheme:false],
|
||||
[[MTDatacenterAuthPublicKey alloc] initWithPublicKey:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAruw2yP/BCcsJliRoW5eBVBVle9dtjJw+OYED160Wybum9SXtBBLX\n"
|
||||
"riwt4rROd9csv0t0OHCaTmRqBcQ0J8fxhN6/cpR1GWgOZRUAiQxoMnlt0R93LCX/\n"
|
||||
"j1dnVa/gVbCjdSxpbrfY2g2L4frzjJvdl84Kd9ORYjDEAyFnEA7dD556OptgLQQ2\n"
|
||||
"e2iVNq8NZLYTzLp5YpOdO1doK+ttrltggTCy5SrKeLoCPPbOgGsdxJxyz5KKcZnS\n"
|
||||
"Lj16yE5HvJQn0CNpRdENvRUXe6tBP78O39oJ8BTHp9oIjd6XWXAsp2CvK45Ol8wF\n"
|
||||
"XGF710w9lwCGNbmNxNYhtIkdqfsEcwR5JwIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----" usesModernPaddingScheme:false],
|
||||
[[MTDatacenterAuthPublicKey alloc] initWithPublicKey:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAvfLHfYH2r9R70w8prHblWt/nDkh+XkgpflqQVcnAfSuTtO05lNPs\n"
|
||||
"pQmL8Y2XjVT4t8cT6xAkdgfmmvnvRPOOKPi0OfJXoRVylFzAQG/j83u5K3kRLbae\n"
|
||||
"7fLccVhKZhY46lvsueI1hQdLgNV9n1cQ3TDS2pQOCtovG4eDl9wacrXOJTG2990V\n"
|
||||
"jgnIKNA0UMoP+KF03qzryqIt3oTvZq03DyWdGK+AZjgBLaDKSnC6qD2cFY81UryR\n"
|
||||
"WOab8zKkWAnhw2kFpcqhI0jdV5QaSCExvnsjVaX0Y1N0870931/5Jb9ICe4nweZ9\n"
|
||||
"kSDF/gip3kWLG0o8XQpChDfyvsqB9OLV/wIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----" usesModernPaddingScheme:false],
|
||||
[[MTDatacenterAuthPublicKey alloc] initWithPublicKey:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAs/ditzm+mPND6xkhzwFIz6J/968CtkcSE/7Z2qAJiXbmZ3UDJPGr\n"
|
||||
"zqTDHkO30R8VeRM/Kz2f4nR05GIFiITl4bEjvpy7xqRDspJcCFIOcyXm8abVDhF+\n"
|
||||
"th6knSU0yLtNKuQVP6voMrnt9MV1X92LGZQLgdHZbPQz0Z5qIpaKhdyA8DEvWWvS\n"
|
||||
"Uwwc+yi1/gGaybwlzZwqXYoPOhwMebzKUk0xW14htcJrRrq+PXXQbRzTMynseCoP\n"
|
||||
"Ioke0dtCodbA3qQxQovE16q9zz4Otv2k4j63cz53J+mhkVWAeWxVGI0lltJmWtEY\n"
|
||||
"K6er8VqqWot3nqmWMXogrgRLggv/NbbooQIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----" usesModernPaddingScheme:false],
|
||||
[[MTDatacenterAuthPublicKey alloc] initWithPublicKey:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAvmpxVY7ld/8DAjz6F6q05shjg8/4p6047bn6/m8yPy1RBsvIyvuD\n"
|
||||
"uGnP/RzPEhzXQ9UJ5Ynmh2XJZgHoE9xbnfxL5BXHplJhMtADXKM9bWB11PU1Eioc\n"
|
||||
"3+AXBB8QiNFBn2XI5UkO5hPhbb9mJpjA9Uhw8EdfqJP8QetVsI/xrCEbwEXe0xvi\n"
|
||||
"fRLJbY08/Gp66KpQvy7g8w7VB8wlgePexW3pT13Ap6vuC+mQuJPyiHvSxjEKHgqe\n"
|
||||
"Pji9NP3tJUFQjcECqcm0yV7/2d0t/pbCm+ZH1sadZspQCEPPrtbkQBlvHb4OLiIW\n"
|
||||
"PGHKSMeRFvp3IWcmdJqXahxLCUS1Eh6MAQIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----" usesModernPaddingScheme:false],
|
||||
[[MTDatacenterAuthPublicKey alloc] initWithPublicKey:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAr4v4wxMDXIaMOh8bayF/NyoYdpcysn5EbjTIOZC0RkgzsRj3SGlu\n"
|
||||
"52QSz+ysO41dQAjpFLgxPVJoOlxXokaOq827IfW0bGCm0doT5hxtedu9UCQKbE8j\n"
|
||||
"lDOk+kWMXHPZFJKWRgKgTu9hcB3y3Vk+JFfLpq3d5ZB48B4bcwrRQnzkx5GhWOFX\n"
|
||||
"x73ZgjO93eoQ2b/lDyXxK4B4IS+hZhjzezPZTI5upTRbs5ljlApsddsHrKk6jJNj\n"
|
||||
"8Ygs/ps8e6ct82jLXbnndC9s8HjEvDvBPH9IPjv5JUlmHMBFZ5vFQIfbpo0u0+1P\n"
|
||||
"n6bkEi5o7/ifoyVv2pAZTRwppTz0EuXD8QIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----" usesModernPaddingScheme:false],
|
||||
[[MTDatacenterAuthPublicKey alloc] initWithPublicKey:@"-----BEGIN RSA PUBLIC KEY-----\n"
|
||||
"MIIBCgKCAQEAyMEdY1aR+sCR3ZSJrtztKTKqigvO/vBfqACJLZtS7QMgCGXJ6XIR\n"
|
||||
"yy7mx66W0/sOFa7/1mAZtEoIokDP3ShoqF4fVNb6XeqgQfaUHd8wJpDWHcR2OFwv\n"
|
||||
"plUUI1PLTktZ9uW2WE23b+ixNwJjJGwBDJPQEQFBE+vfmH0JP503wr5INS1poWg/\n"
|
||||
"j25sIWeYPHYeOrFp/eXaqhISP6G+q2IeTaWTXpwZj4LzXq5YOpk4bYEQ6mvRq7D1\n"
|
||||
"aHWfYmlEGepfaYR8Q0YqvvhYtMte3ITnuSJs171+GDqpdKcSwHnd6FudwGO4pcCO\n"
|
||||
"j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB\n"
|
||||
"-----END RSA PUBLIC KEY-----" usesModernPaddingScheme:true]
|
||||
];
|
||||
});
|
||||
return serverPublicKeys;
|
||||
}
|
||||
|
||||
static NSDictionary *selectPublicKey(NSArray *fingerprints, NSArray<NSDictionary *> *publicKeys)
|
||||
{
|
||||
for (NSNumber *nFingerprint in fingerprints)
|
||||
{
|
||||
for (NSDictionary *keyDesc in publicKeys)
|
||||
{
|
||||
uint64_t keyFingerprint = [[keyDesc objectForKey:@"fingerprint"] unsignedLongLongValue];
|
||||
static MTDatacenterAuthPublicKey *selectPublicKey(id<EncryptionProvider> encryptionProvider, NSArray<NSNumber *> *fingerprints, NSArray<MTDatacenterAuthPublicKey *> *publicKeys, bool onlyModernPadding) {
|
||||
for (NSNumber *nFingerprint in fingerprints) {
|
||||
for (MTDatacenterAuthPublicKey *key in publicKeys) {
|
||||
if (onlyModernPadding) {
|
||||
if (!key.usesModernPaddingScheme) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
uint64_t keyFingerprint = [key fingerprintWithEncryptionProvider:encryptionProvider];
|
||||
|
||||
if ([nFingerprint unsignedLongLongValue] == keyFingerprint)
|
||||
return keyDesc;
|
||||
if ([nFingerprint unsignedLongLongValue] == keyFingerprint) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,7 +185,7 @@ typedef enum {
|
||||
MTDatacenterAuthKey *_authKey;
|
||||
NSData *_encryptedClientData;
|
||||
|
||||
NSArray<NSDictionary *> *_publicKeys;
|
||||
NSArray<MTDatacenterAuthPublicKey *> *_publicKeys;
|
||||
}
|
||||
|
||||
@end
|
||||
@ -168,6 +203,17 @@ typedef enum {
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSArray<MTDatacenterAuthPublicKey *> *)convertPublicKeysFromDictionaries:(NSArray<NSDictionary *> *)list {
|
||||
NSMutableArray<MTDatacenterAuthPublicKey *> *cdnKeys = [[NSMutableArray alloc] init];
|
||||
for (NSDictionary *dict in list) {
|
||||
NSString *key = dict[@"key"];
|
||||
if ([key isKindOfClass:[NSString class]]) {
|
||||
[cdnKeys addObject:[[MTDatacenterAuthPublicKey alloc] initWithPublicKey:key usesModernPaddingScheme:false]];
|
||||
}
|
||||
}
|
||||
return cdnKeys;
|
||||
}
|
||||
|
||||
- (void)reset:(MTProto *)mtProto
|
||||
{
|
||||
_currentStageMessageId = 0;
|
||||
@ -187,8 +233,8 @@ typedef enum {
|
||||
_encryptedClientData = nil;
|
||||
|
||||
if (mtProto.cdn) {
|
||||
_publicKeys = [mtProto.context publicKeysForDatacenterWithId:mtProto.datacenterId];
|
||||
if (_publicKeys == nil) {
|
||||
_publicKeys = [self convertPublicKeysFromDictionaries:[mtProto.context publicKeysForDatacenterWithId:mtProto.datacenterId]];
|
||||
if (_publicKeys.count == 0) {
|
||||
_stage = MTDatacenterAuthStageWaitingForPublicKeys;
|
||||
[mtProto.context publicKeysForDatacenterWithIdRequired:mtProto.datacenterId];
|
||||
} else {
|
||||
@ -211,7 +257,7 @@ typedef enum {
|
||||
- (void)mtProtoPublicKeysUpdated:(MTProto *)mtProto datacenterId:(NSInteger)datacenterId publicKeys:(NSArray<NSDictionary *> *)publicKeys {
|
||||
if (_stage == MTDatacenterAuthStageWaitingForPublicKeys) {
|
||||
if (mtProto.datacenterId == datacenterId) {
|
||||
_publicKeys = publicKeys;
|
||||
_publicKeys = [self convertPublicKeysFromDictionaries:publicKeys];
|
||||
if (_publicKeys != nil && _publicKeys.count != 0) {
|
||||
_stage = MTDatacenterAuthStagePQ;
|
||||
[mtProto requestTransportTransaction];
|
||||
@ -238,7 +284,7 @@ typedef enum {
|
||||
}
|
||||
|
||||
MTBuffer *reqPqBuffer = [[MTBuffer alloc] init];
|
||||
[reqPqBuffer appendInt32:(int32_t)0x60469778];
|
||||
[reqPqBuffer appendInt32:(int32_t)0xbe7e8ef1];
|
||||
[reqPqBuffer appendBytes:_nonce.bytes length:_nonce.length];
|
||||
|
||||
NSString *messageDescription = [NSString stringWithFormat:@"reqPq nonce:%@", _nonce];
|
||||
@ -306,6 +352,178 @@ typedef enum {
|
||||
return nil;
|
||||
}
|
||||
|
||||
static NSData *aesCbcEncrypt(NSData *data, NSData *key, NSData *iv) {
|
||||
size_t keyLength = kCCKeySizeAES256;
|
||||
if (key.length != keyLength) {
|
||||
return nil;
|
||||
}
|
||||
if (iv.length != 16) {
|
||||
return nil;
|
||||
}
|
||||
if (data.length % 16 != 0) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSMutableData *outData = [[NSMutableData alloc] initWithLength:data.length];
|
||||
|
||||
CCOperation operation = kCCEncrypt;
|
||||
CCAlgorithm algoritm = kCCAlgorithmAES128;
|
||||
CCOptions options = 0; // No padding
|
||||
|
||||
size_t outDataActualSize = 0;
|
||||
|
||||
int status = CCCrypt(
|
||||
operation,
|
||||
algoritm,
|
||||
options,
|
||||
key.bytes,
|
||||
keyLength,
|
||||
iv.bytes,
|
||||
data.bytes,
|
||||
data.length,
|
||||
outData.mutableBytes,
|
||||
outData.length,
|
||||
&outDataActualSize
|
||||
);
|
||||
|
||||
if (status != kCCSuccess) {
|
||||
return nil;
|
||||
}
|
||||
if (outDataActualSize != data.length) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
return outData;
|
||||
}
|
||||
|
||||
static NSData *encryptRSALegacy(id<EncryptionProvider> encryptionProvider, NSData *pqInnerData, NSString *publicKey) {
|
||||
NSMutableData *dataWithHash = [[NSMutableData alloc] init];
|
||||
[dataWithHash appendData:MTSha1(pqInnerData)];
|
||||
[dataWithHash appendData:pqInnerData];
|
||||
while (dataWithHash.length < 255) {
|
||||
uint8_t random = 0;
|
||||
arc4random_buf(&random, 1);
|
||||
[dataWithHash appendBytes:&random length:1];
|
||||
}
|
||||
|
||||
NSData *encryptedData = MTRsaEncrypt(encryptionProvider, publicKey, dataWithHash);
|
||||
|
||||
if (encryptedData.length < 256) {
|
||||
NSMutableData *newEncryptedData = [[NSMutableData alloc] init];
|
||||
for (int i = 0; i < 256 - (int)encryptedData.length; i++)
|
||||
{
|
||||
uint8_t random = 0;
|
||||
arc4random_buf(&random, 1);
|
||||
[newEncryptedData appendBytes:&random length:1];
|
||||
}
|
||||
[newEncryptedData appendData:encryptedData];
|
||||
encryptedData = newEncryptedData;
|
||||
}
|
||||
|
||||
return encryptedData;
|
||||
}
|
||||
|
||||
static NSData *encryptRSAModernPadding(id<EncryptionProvider> encryptionProvider, NSData *pqInnerData, NSString *publicKey) {
|
||||
NSMutableData *dataWithPadding = [[NSMutableData alloc] init];
|
||||
[dataWithPadding appendData:pqInnerData];
|
||||
if (dataWithPadding.length > 176) {
|
||||
return nil;
|
||||
}
|
||||
if (dataWithPadding.length != 176) {
|
||||
int originalLength = (int)dataWithPadding.length;
|
||||
int numPaddingBytes = 176 - originalLength;
|
||||
[dataWithPadding setLength:176];
|
||||
int randomResult = SecRandomCopyBytes(kSecRandomDefault, numPaddingBytes, ((uint8_t *)dataWithPadding.mutableBytes) + originalLength);
|
||||
if (randomResult != errSecSuccess) {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
NSMutableData *dataWithHash = [[NSMutableData alloc] init];
|
||||
[dataWithHash appendData:dataWithPadding];
|
||||
[dataWithHash appendData:MTSha256(dataWithPadding)];
|
||||
if (dataWithHash.length != 208) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
int randomResult = 0;
|
||||
NSMutableData *tempKey = [[NSMutableData alloc] initWithLength:32];
|
||||
randomResult = SecRandomCopyBytes(kSecRandomDefault, tempKey.length, tempKey.mutableBytes);
|
||||
if (randomResult != errSecSuccess) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSMutableData *tempIv = [[NSMutableData alloc] initWithLength:16];
|
||||
randomResult = SecRandomCopyBytes(kSecRandomDefault, tempIv.length, tempIv.mutableBytes);
|
||||
if (randomResult != errSecSuccess) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSData *aesEncrypted = aesCbcEncrypt(dataWithHash, tempKey, tempIv);
|
||||
if (aesEncrypted == nil) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSMutableData *tempIvPlusAesEncrypted = [[NSMutableData alloc] init];
|
||||
[tempIvPlusAesEncrypted appendData:tempIv];
|
||||
[tempIvPlusAesEncrypted appendData:aesEncrypted];
|
||||
NSData *shaTempIvPlusAesEncrypted = MTSha256(tempIvPlusAesEncrypted);
|
||||
|
||||
NSMutableData *tempKeyXor = [[NSMutableData alloc] initWithLength:tempKey.length];
|
||||
if (tempKeyXor.length != shaTempIvPlusAesEncrypted.length) {
|
||||
return nil;
|
||||
}
|
||||
for (NSUInteger i = 0; i < tempKey.length; i++) {
|
||||
((uint8_t *)tempKeyXor.mutableBytes)[i] = ((uint8_t *)tempKey.bytes)[i] ^ ((uint8_t *)shaTempIvPlusAesEncrypted.bytes)[i];
|
||||
}
|
||||
|
||||
NSMutableData *keyAesEncrypted = [[NSMutableData alloc] init];
|
||||
[keyAesEncrypted appendData:tempKeyXor];
|
||||
[keyAesEncrypted appendData:tempIv];
|
||||
[keyAesEncrypted appendData:aesEncrypted];
|
||||
if (keyAesEncrypted.length != 256) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
id<MTBignumContext> bignumContext = [encryptionProvider createBignumContext];
|
||||
if (bignumContext == nil) {
|
||||
return nil;
|
||||
}
|
||||
id<MTRsaPublicKey> rsaPublicKey = [encryptionProvider parseRSAPublicKey:publicKey];
|
||||
if (rsaPublicKey == nil) {
|
||||
return nil;
|
||||
}
|
||||
id<MTBignum> rsaModule = [bignumContext rsaGetN:rsaPublicKey];
|
||||
if (rsaModule == nil) {
|
||||
return nil;
|
||||
}
|
||||
id<MTBignum> bignumKeyAesEncrypted = [bignumContext create];
|
||||
if (bignumKeyAesEncrypted == nil) {
|
||||
return nil;
|
||||
}
|
||||
[bignumContext assignBinTo:bignumKeyAesEncrypted value:keyAesEncrypted];
|
||||
int compareResult = [bignumContext compare:rsaModule with:bignumKeyAesEncrypted];
|
||||
if (compareResult == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NSData *encryptedData = [encryptionProvider rsaEncryptWithPublicKey:publicKey data:keyAesEncrypted];
|
||||
NSMutableData *paddedEncryptedData = [[NSMutableData alloc] init];
|
||||
[paddedEncryptedData appendData:encryptedData];
|
||||
while (paddedEncryptedData.length < 256) {
|
||||
uint8_t zero = 0;
|
||||
[paddedEncryptedData replaceBytesInRange:NSMakeRange(0, 0) withBytes:&zero];
|
||||
}
|
||||
|
||||
if (paddedEncryptedData.length != 256) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
return paddedEncryptedData;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector
|
||||
{
|
||||
if (_stage == MTDatacenterAuthStagePQ && [message.body isKindOfClass:[MTResPqMessage class]])
|
||||
@ -314,10 +532,13 @@ typedef enum {
|
||||
|
||||
if ([_nonce isEqualToData:resPqMessage.nonce])
|
||||
{
|
||||
NSDictionary *publicKey = selectPublicKey(resPqMessage.serverPublicKeyFingerprints, _publicKeys);
|
||||
MTDatacenterAuthPublicKey *publicKey = selectPublicKey(_encryptionProvider, resPqMessage.serverPublicKeyFingerprints, _publicKeys, true);
|
||||
if (publicKey == nil) {
|
||||
publicKey = selectPublicKey(mtProto.context.encryptionProvider, resPqMessage.serverPublicKeyFingerprints, _publicKeys, false);
|
||||
}
|
||||
|
||||
if (publicKey == nil && mtProto.cdn && resPqMessage.serverPublicKeyFingerprints.count == 1 && _publicKeys.count == 1) {
|
||||
publicKey = @{@"key": _publicKeys[0][@"key"], @"fingerprint": resPqMessage.serverPublicKeyFingerprints[0]};
|
||||
publicKey = _publicKeys[0];
|
||||
}
|
||||
|
||||
if (publicKey == nil)
|
||||
@ -367,7 +588,7 @@ typedef enum {
|
||||
} while (q > 0);
|
||||
_dhQ = qBytes;
|
||||
|
||||
_dhPublicKeyFingerprint = [[publicKey objectForKey:@"fingerprint"] longLongValue];
|
||||
_dhPublicKeyFingerprint = [publicKey fingerprintWithEncryptionProvider:_encryptionProvider];
|
||||
|
||||
uint8_t nonceBytes[32];
|
||||
__unused int result = SecRandomCopyBytes(kSecRandomDefault, 32, nonceBytes);
|
||||
@ -390,37 +611,17 @@ typedef enum {
|
||||
[innerDataBuffer appendInt32:mtProto.context.tempKeyExpiration];
|
||||
|
||||
NSData *innerDataBytes = innerDataBuffer.data;
|
||||
|
||||
NSMutableData *dataWithHash = [[NSMutableData alloc] init];
|
||||
[dataWithHash appendData:MTSha1(innerDataBytes)];
|
||||
[dataWithHash appendData:innerDataBytes];
|
||||
while (dataWithHash.length < 255)
|
||||
{
|
||||
uint8_t random = 0;
|
||||
arc4random_buf(&random, 1);
|
||||
[dataWithHash appendBytes:&random length:1];
|
||||
NSData *encryptedData = nil;
|
||||
if (publicKey.usesModernPaddingScheme) {
|
||||
encryptedData = encryptRSAModernPadding(_encryptionProvider, innerDataBytes, publicKey.publicKey);
|
||||
} else {
|
||||
encryptedData = encryptRSALegacy(_encryptionProvider, innerDataBytes, publicKey.publicKey);
|
||||
}
|
||||
|
||||
NSData *encryptedData = MTRsaEncrypt(_encryptionProvider, [publicKey objectForKey:@"key"], dataWithHash);
|
||||
|
||||
if (MTLogEnabled()) {
|
||||
MTLog(@"[MTDatacenterAuthMessageService#%p encryptedData length %d dataWithHash length %d]", self, (int)encryptedData.length, (int)dataWithHash.length);
|
||||
MTLog(@"[MTDatacenterAuthMessageService#%p encryptedData length %d]", self, (int)encryptedData.length);
|
||||
}
|
||||
if (encryptedData.length < 256)
|
||||
{
|
||||
NSMutableData *newEncryptedData = [[NSMutableData alloc] init];
|
||||
for (int i = 0; i < 256 - (int)encryptedData.length; i++)
|
||||
{
|
||||
uint8_t random = 0;
|
||||
arc4random_buf(&random, 1);
|
||||
[newEncryptedData appendBytes:&random length:1];
|
||||
}
|
||||
[newEncryptedData appendData:encryptedData];
|
||||
encryptedData = newEncryptedData;
|
||||
}
|
||||
#if DEBUG
|
||||
assert(encryptedData.length == 256);
|
||||
#endif
|
||||
|
||||
|
||||
_dhEncryptedData = encryptedData;
|
||||
} else {
|
||||
MTBuffer *innerDataBuffer = [[MTBuffer alloc] init];
|
||||
@ -433,42 +634,30 @@ typedef enum {
|
||||
[innerDataBuffer appendBytes:_newNonce.bytes length:_newNonce.length];
|
||||
|
||||
NSData *innerDataBytes = innerDataBuffer.data;
|
||||
|
||||
NSMutableData *dataWithHash = [[NSMutableData alloc] init];
|
||||
[dataWithHash appendData:MTSha1(innerDataBytes)];
|
||||
[dataWithHash appendData:innerDataBytes];
|
||||
while (dataWithHash.length < 255)
|
||||
{
|
||||
uint8_t random = 0;
|
||||
arc4random_buf(&random, 1);
|
||||
[dataWithHash appendBytes:&random length:1];
|
||||
}
|
||||
|
||||
NSData *encryptedData = MTRsaEncrypt(_encryptionProvider, [publicKey objectForKey:@"key"], dataWithHash);
|
||||
if (MTLogEnabled()) {
|
||||
MTLog(@"[MTDatacenterAuthMessageService#%p encryptedData length %d dataWithHash length %d]", self, (int)encryptedData.length, (int)dataWithHash.length);
|
||||
}
|
||||
if (encryptedData.length < 256)
|
||||
{
|
||||
NSMutableData *newEncryptedData = [[NSMutableData alloc] init];
|
||||
for (int i = 0; i < 256 - (int)encryptedData.length; i++)
|
||||
{
|
||||
uint8_t random = 0;
|
||||
arc4random_buf(&random, 1);
|
||||
[newEncryptedData appendBytes:&random length:1];
|
||||
}
|
||||
[newEncryptedData appendData:encryptedData];
|
||||
encryptedData = newEncryptedData;
|
||||
NSData *encryptedData = nil;
|
||||
if (publicKey.usesModernPaddingScheme) {
|
||||
encryptedData = encryptRSAModernPadding(_encryptionProvider, innerDataBytes, publicKey.publicKey);
|
||||
} else {
|
||||
encryptedData = encryptRSALegacy(_encryptionProvider, innerDataBytes, publicKey.publicKey);
|
||||
}
|
||||
|
||||
_dhEncryptedData = encryptedData;
|
||||
}
|
||||
|
||||
_stage = MTDatacenterAuthStageReqDH;
|
||||
_currentStageMessageId = 0;
|
||||
_currentStageMessageSeqNo = 0;
|
||||
_currentStageTransactionId = nil;
|
||||
[mtProto requestTransportTransaction];
|
||||
|
||||
if (_dhEncryptedData == nil) {
|
||||
_stage = MTDatacenterAuthStagePQ;
|
||||
_currentStageMessageId = 0;
|
||||
_currentStageMessageSeqNo = 0;
|
||||
_currentStageTransactionId = nil;
|
||||
[mtProto requestTransportTransaction];
|
||||
} else {
|
||||
_stage = MTDatacenterAuthStageReqDH;
|
||||
_currentStageMessageId = 0;
|
||||
_currentStageMessageSeqNo = 0;
|
||||
_currentStageTransactionId = nil;
|
||||
[mtProto requestTransportTransaction];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,14 @@
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"res_pq nonce:%@ serverNonce:%@ pq:%@ fingerprints:%@", _nonce, _serverNonce, _pq, _serverPublicKeyFingerprints];
|
||||
NSMutableString *fingerprintsString = [[NSMutableString alloc] init];
|
||||
for (NSNumber *value in _serverPublicKeyFingerprints) {
|
||||
if (fingerprintsString.length != 0) {
|
||||
[fingerprintsString appendString:@"\n"];
|
||||
}
|
||||
[fingerprintsString appendFormat:@"%llx", [value longLongValue]];
|
||||
}
|
||||
return [NSString stringWithFormat:@"res_pq nonce:%@ serverNonce:%@ pq:%@ fingerprints:%@", _nonce, _serverNonce, _pq, fingerprintsString];
|
||||
}
|
||||
|
||||
@end
|
||||
|
Loading…
x
Reference in New Issue
Block a user