示例#1
0
        public void ChangePassword()
        {
            if (!CanChangePassword)
            {
                return;
            }
            if (_passwordBase == null)
            {
                return;
            }

            var newSaltData = TLUtils.Combine(_passwordBase.NewSalt.Data, TLLong.Random().ToBytes());
            var newSalt     = TLString.FromBigEndianData(newSaltData);

            var sha = new SHA256Managed();
            var newPasswordHashData = sha.ComputeHash(TLUtils.Combine(newSalt.Data, new TLString(_password).Data, newSalt.Data));
            var newPasswordHash     = TLString.FromBigEndianData(newPasswordHashData);

            var newSettings = new TLPasswordInputSettings
            {
                NewSalt         = newSalt,
                NewPasswordHash = newPasswordHash,
                Hint            = TLString.Empty
            };

            _passwordBase.TempNewPassword = Password;

            StateService.Password            = _passwordBase;
            StateService.NewPasswordSettings = newSettings;
            StateService.RemoveBackEntry     = true;
            NavigationService.UriFor <ChangePasswordHintViewModel>().Navigate();

            return;
        }
        private static byte[] ComposeSignUpRequest(string phone, TLString phoneCodeHash, TLString phoneCode, TLString firstName, TLString lastName)
        {
            TLUtils.WriteLine("--Compose SignUp request--");
            //#1b067634x
            var signature = new byte[] { 0x34, 0x76, 0x06, 0x1b };

            var phoneNumberBytes = Encoding.UTF8.GetBytes(phone);
            var phoneNumberStr   = TLString.FromBigEndianData(phoneNumberBytes.ToArray());

            TLUtils.WriteLine("Phone: " + BitConverter.ToString(phoneNumberBytes));
            TLUtils.WriteLine("Phone serialized: " + BitConverter.ToString(phoneNumberStr.ToBytes()));

            TLUtils.WriteLine("PhoneCodeHash: " + phoneCodeHash.ToString());
            TLUtils.WriteLine("PhoneCodeHash serialized: " + BitConverter.ToString(phoneCodeHash.ToBytes()));

            TLUtils.WriteLine("PhoneCode: " + phoneCode.ToString());
            TLUtils.WriteLine("PhoneCode serialized: " + BitConverter.ToString(phoneCode.ToBytes()));

            TLUtils.WriteLine("FirstName: " + firstName.ToString());
            TLUtils.WriteLine("FirstName serialized: " + BitConverter.ToString(firstName.ToBytes()));

            TLUtils.WriteLine("LastName: " + lastName.ToString());
            TLUtils.WriteLine("LastName serialized: " + BitConverter.ToString(lastName.ToBytes()));

            return(signature
                   .Concat(phoneNumberStr.ToBytes())
                   .Concat(phoneCodeHash.ToBytes())
                   .Concat(phoneCode.ToBytes())
                   .Concat(firstName.ToBytes())
                   .Concat(lastName.ToBytes())
                   .ToArray());
        }
示例#3
0
        private void CalculateSecretChatParamsAsync()
        {
            MTProtoService.GetDHConfigAsync(new TLInt(0), new TLInt(0),
                                            result =>
            {
                var dhConfig = (TLDHConfig)result;
                if (!TLUtils.CheckPrime(dhConfig.P.Data, dhConfig.G.Value))
                {
                    return;
                }

                var aBytes = new byte[256];
                var random = new SecureRandom();
                random.NextBytes(aBytes);
                _a = TLString.FromBigEndianData(aBytes);
                _p = dhConfig.P;
                _g = dhConfig.G;

                var gaBytes = Telegram.Api.Services.MTProtoService.GetGB(aBytes, dhConfig.G, dhConfig.P);
                _ga         = TLString.FromBigEndianData(gaBytes);
                if (_invokeDelayedUserAction)
                {
                    _invokeDelayedUserAction = false;
                    CreateSecretChat();
                }
            },
                                            error =>
            {
                Execute.ShowDebugMessage("messages.getDhConfig error: " + error);
            });
        }
示例#4
0
        public static async Task <Tuple <bool, byte[]> > FillBuffer(IStorageFile file, UploadablePart part)
        {
            try
            {
                if (part.ParentItem.FileNotFound)
                {
                    return(new Tuple <bool, byte[]>(false, null));
                }

                using (var stream = await file.OpenAsync(FileAccessMode.Read))
                {
                    using (var inStream = stream.GetInputStreamAt((ulong)part.Position))
                    {
                        var bytes = new byte[part.Count];
                        using (var reader = new DataReader(inStream))
                        {
                            await reader.LoadAsync((uint)bytes.Length);

                            reader.ReadBytes(bytes);
                        }

                        // encrypting part
                        if (part.ParentItem.Key != null &&
                            part.ParentItem.IV != null)
                        {
                            var key = part.ParentItem.Key;
                            var iv  = part.FilePart.Value == 0 ? part.ParentItem.IV : part.IV;

                            if (iv == null)
                            {
                                return(new Tuple <bool, byte[]>(true, null));
                            }

                            byte[] nextIV;

                            var encryptedBytes = Utils.AesIge(bytes, key.Data, iv.Data, true, out nextIV);
                            bytes = encryptedBytes;

                            var nextPartId = part.FilePart.Value + 1;
                            if (part.ParentItem.Parts.Count > nextPartId)
                            {
                                part.ParentItem.Parts[nextPartId].IV = TLString.FromBigEndianData(nextIV);
                            }
                        }

                        return(new Tuple <bool, byte[]>(true, bytes));
                    }
                }
            }
            catch (FileNotFoundException ex)
            {
                Execute.ShowDebugMessage("FillBuffer FileNotFoundException\n" + ex);
                return(new Tuple <bool, byte[]>(false, null));
            }
            catch (Exception ex)
            {
                Execute.ShowDebugMessage("FillBuffer Exception\n" + ex);
                return(new Tuple <bool, byte[]>(true, null));
            }
        }
示例#5
0
        public static TLString GetVBytes(TLString passwordBytes, TLPasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow algo)
        {
            if (!TLUtils.CheckPrime(algo.P.Data, algo.G.Value))
            {
                return(null);
            }

            return(TLString.FromBigEndianData(GetBigIntegerBytes(GetV(passwordBytes, algo))));
        }
示例#6
0
        public static long GetRSAFingerprint(string key)
        {
            using (var text = new StringReader(key))
            {
                var reader    = new PemReader(text);
                var parameter = reader.ReadObject() as RsaKeyParameters;
                if (parameter != null)
                {
                    var modulus  = parameter.Modulus.ToByteArray();
                    var exponent = parameter.Exponent.ToByteArray();

                    if (modulus.Length > 256)
                    {
                        var corrected = new byte[256];
                        Buffer.BlockCopy(modulus, modulus.Length - 256, corrected, 0, 256);

                        modulus = corrected;
                    }
                    else if (modulus.Length < 256)
                    {
                        var corrected = new byte[256];
                        Buffer.BlockCopy(modulus, 0, corrected, 256 - modulus.Length, modulus.Length);

                        for (int a = 0; a < 256 - modulus.Length; a++)
                        {
                            modulus[a] = 0;
                        }

                        modulus = corrected;
                    }

                    using (var stream = new MemoryStream())
                    {
                        var modulusString  = TLString.FromBigEndianData(modulus);
                        var exponentString = TLString.FromBigEndianData(exponent);

                        modulusString.ToStream(stream);
                        exponentString.ToStream(stream);

                        var hash = ComputeSHA1(stream.ToArray());

                        var fingerprint = (((ulong)hash[19]) << 56) |
                                          (((ulong)hash[18]) << 48) |
                                          (((ulong)hash[17]) << 40) |
                                          (((ulong)hash[16]) << 32) |
                                          (((ulong)hash[15]) << 24) |
                                          (((ulong)hash[14]) << 16) |
                                          (((ulong)hash[13]) << 8) |
                                          ((ulong)hash[12]);

                        return((long)fingerprint);
                    }
                }
            }

            return(-1);
        }
        private static byte[] ComposeSaveDeveloperInfoRequest()
        {
            TLUtils.WriteLine("--Compose save developer info--");

            var saveDeveloperInfoBytes = new byte[] { 0x95, 0x6e, 0x5f, 0x9a };

            Int32 vkID      = 210427;
            var   vkIDBytes = BitConverter.GetBytes(vkID);

            TLUtils.WriteLine("VK ID");
            TLUtils.WriteLine(BitConverter.ToString(vkIDBytes));

            var name      = "Evgeny Nadymov";
            var nameBytes = Encoding.UTF8.GetBytes(name); // little endian
            var nameStr   = TLString.FromBigEndianData(nameBytes.ToArray());

            TLUtils.WriteLine("Name");
            TLUtils.WriteLine(BitConverter.ToString(nameBytes));
            TLUtils.WriteLine("Name serialized");
            TLUtils.WriteLine(BitConverter.ToString(nameStr.ToBytes()));

            var phoneNumber      = "+79052636554";
            var phoneNumberBytes = Encoding.UTF8.GetBytes(phoneNumber);
            var phoneNumberStr   = TLString.FromBigEndianData(phoneNumberBytes.ToArray());

            TLUtils.WriteLine("Phone");
            TLUtils.WriteLine(BitConverter.ToString(phoneNumberBytes));
            TLUtils.WriteLine("Phone serialized");
            TLUtils.WriteLine(BitConverter.ToString(phoneNumberStr.ToBytes()));


            Int32 age      = 25;
            var   ageBytes = BitConverter.GetBytes(age);

            TLUtils.WriteLine("Age");
            TLUtils.WriteLine(BitConverter.ToString(ageBytes));


            var city      = "SPb";
            var cityBytes = Encoding.UTF8.GetBytes(city);
            var cityStr   = TLString.FromBigEndianData(cityBytes.ToArray());

            TLUtils.WriteLine("City");
            TLUtils.WriteLine(BitConverter.ToString(cityBytes));
            TLUtils.WriteLine("City serialized");
            TLUtils.WriteLine(BitConverter.ToString(cityStr.ToBytes()));

            TLUtils.WriteLine("---------------------------------");

            return(saveDeveloperInfoBytes
                   .Concat(vkIDBytes)
                   .Concat(nameStr.ToBytes())
                   .Concat(phoneNumberStr.ToBytes())
                   .Concat(ageBytes)
                   .Concat(cityStr.ToBytes())
                   .ToArray());
        }
示例#8
0
        public static TLString GetX(TLString password, TLPasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow algo)
        {
            var x_bytes = Telegram.Api.Helpers.Utils.ComputeSHA256(TLUtils.Combine(algo.Salt1.Data, password.Data, algo.Salt1.Data));

            x_bytes = Telegram.Api.Helpers.Utils.ComputeSHA256(TLUtils.Combine(algo.Salt2.Data, x_bytes, algo.Salt2.Data));
            x_bytes = PBKDF2.GetHash(x_bytes.AsBuffer(), algo.Salt1.Data.AsBuffer()).ToArray();
            x_bytes = Telegram.Api.Helpers.Utils.ComputeSHA256(TLUtils.Combine(algo.Salt2.Data, x_bytes, algo.Salt2.Data));

            return(TLString.FromBigEndianData(x_bytes));
        }
        private void SendDocument(Photo p)
        {
            var chat = Chat as TLEncryptedChat;

            if (chat == null)
            {
                return;
            }

            var dcId       = TLInt.Random();
            var id         = TLLong.Random();
            var accessHash = TLLong.Random();

            var fileLocation = new TLEncryptedFile
            {
                Id             = id,
                AccessHash     = accessHash,
                DCId           = dcId,
                Size           = new TLInt(p.Bytes.Length),
                KeyFingerprint = new TLInt(0),
                FileName       = new TLString(Path.GetFileName(p.FileName))
            };

            var fileName = String.Format("{0}_{1}_{2}.jpg",
                                         fileLocation.Id,
                                         fileLocation.DCId,
                                         fileLocation.AccessHash);

            using (var store = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (var fileStream = store.CreateFile(fileName))
                {
                    fileStream.Write(p.Bytes, 0, p.Bytes.Length);
                }
            }

            var keyIV = GenerateKeyIV();

            int thumbHeight;
            int thumbWidth;
            var thumb = ImageUtils.CreateThumb(p.Bytes, Constants.DocumentPreviewMaxSize, Constants.DocumentPreviewQuality, out thumbHeight, out thumbWidth);

            var decryptedMediaDocument = GetDecryptedMediaDocument(p, chat, TLString.FromBigEndianData(thumb), new TLInt(thumbWidth), new TLInt(thumbHeight), new TLString("image/jpeg"), keyIV, fileLocation);

            var decryptedTuple = GetDecryptedMessageAndObject(TLString.Empty, decryptedMediaDocument, chat, true);

            InsertSendingMessage(decryptedTuple.Item1);
            RaiseScrollToBottom();
            NotifyOfPropertyChange(() => DescriptionVisibility);

            BeginOnThreadPool(() =>
                              CacheService.SyncDecryptedMessage(decryptedTuple.Item1, chat,
                                                                cachedMessage => SendDocumentInternal(p.Bytes, decryptedTuple.Item2)));
        }
        public static Telegram.Api.WindowsPhone.Tuple <TLString, TLString> GenerateKeyIV()
        {
            var random = new Random();

            var key = new byte[32];
            var iv  = new byte[32];

            random.NextBytes(key);
            random.NextBytes(iv);

            return(new Telegram.Api.WindowsPhone.Tuple <TLString, TLString>(TLString.FromBigEndianData(key), TLString.FromBigEndianData(iv)));
        }
示例#11
0
        public void GetDHConfig()
        {
            if (_dhConfig != null)
            {
                return;
            }

            _isGettingConfig = true;
            MTProtoService.GetDHConfigAsync(new TLInt(0), new TLInt(0),
                                            result =>
            {
                var dhConfig = result as TLDHConfig;
                if (dhConfig == null)
                {
                    return;
                }
                if (!TLUtils.CheckPrime(dhConfig.P.Data, dhConfig.G.Value))
                {
                    return;
                }

                var aBytes = new byte[256];
                var random = new SecureRandom();
                random.NextBytes(aBytes);

                var gaBytes = Telegram.Api.Services.MTProtoService.GetGB(aBytes, dhConfig.G, dhConfig.P);

                dhConfig.A  = TLString.FromBigEndianData(aBytes);
                dhConfig.GA = TLString.FromBigEndianData(gaBytes);

                _isGettingConfig = false;

                Execute.BeginOnUIThread(() =>
                {
                    _dhConfig = dhConfig;

                    if (_contact != null)
                    {
                        UserAction(_contact);
                    }
                });
            },
                                            error =>
            {
                _isGettingConfig = false;

                IsWorking = false;
                NotifyOfPropertyChange(() => IsNotWorking);
                NotifyOfPropertyChange(() => ProgressVisibility);
                Execute.ShowDebugMessage("messages.getDhConfig error: " + error);
            });
        }
示例#12
0
        private void Rekey()
        {
            var chat = Chat as TLEncryptedChat20;

            if (chat == null)
            {
                return;
            }
            if (chat.PFS_ExchangeId != null)
            {
                return;
            }

            var layer = chat.Layer;

            if (layer.Value < 20)
            {
                return;
            }

            var aBytes = new byte[256];
            var random = new SecureRandom();

            random.NextBytes(aBytes);
            var p = chat.P;
            var g = chat.G;

            var gaBytes = Telegram.Api.Services.MTProtoService.GetGB(aBytes, g, p);
            var ga      = TLString.FromBigEndianData(gaBytes);

            var randomId = TLLong.Random();

            chat.PFS_A          = TLString.FromBigEndianData(aBytes);
            chat.PFS_ExchangeId = randomId;
            var actionRequestKey = new TLDecryptedMessageActionRequestKey {
                ExchangeId = randomId, GA = ga
            };
            var decryptedTuple = GetDecryptedServiceMessageAndObject(actionRequestKey, chat, MTProtoService.CurrentUserId, CacheService);

            decryptedTuple.Item1.Unread = TLBool.False;
#if DEBUG
            Items.Insert(0, decryptedTuple.Item1);
#endif

            SendEncryptedService(chat, decryptedTuple.Item2, MTProtoService, CacheService,
                                 result =>
            {
            });
        }
        private bool PutBigFile(TLLong fileId, TLInt filePart, TLInt fileTotalParts, byte[] bytes)
        {
            var manualResetEvent = new ManualResetEvent(false);
            var result = false;

            _mtProtoService.SaveBigFilePartAsync(fileId, filePart, fileTotalParts, TLString.FromBigEndianData(bytes),
                savingResult =>
                {
                    result = true;
                    manualResetEvent.Set();
                },
                error =>
                {
                    Execute.BeginOnThreadPool(TimeSpan.FromMilliseconds(1000), () => manualResetEvent.Set());
                });

            manualResetEvent.WaitOne();
            return result;
        }
示例#14
0
        public static TLString GetNewHash(TLPasswordKdfAlgoBase kdfAlgoBase, TLString password)
        {
            var algo = kdfAlgoBase as TLPasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow;

            if (algo != null)
            {
                var salt1 = algo.Salt1;
                var salt2 = algo.Salt2;

                var hash1 = GetHash(salt1, password);
                var hash2 = GetHash(salt2, hash1);
                var hash3 = PBKDF2.GetHash(hash2.Data.AsBuffer(), salt1.Data.AsBuffer());
                var hash4 = GetHash(salt2, TLString.FromBigEndianData(hash3.ToArray()));

                return(hash4);
            }

            return(null);
        }
示例#15
0
        public static void AddClientSalt(TLPasswordKdfAlgoBase algoBase)
        {
            var algo = algoBase as TLPasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow;

            if (algo == null)
            {
                return;
            }

            var secureRandom = new SecureRandom();
            var clientSalt1  = new byte[32];

            secureRandom.NextBytes(clientSalt1);

            var newSalt1Data = TLUtils.Combine(algo.Salt1.Data, clientSalt1);
            var newSalt1     = TLString.FromBigEndianData(newSalt1Data);

            algo.Salt1 = newSalt1;
        }
示例#16
0
        public void Done()
        {
            if (IsWorking)
            {
                return;
            }

            var currentSalt = _passwordBase.CurrentSalt;

            var sha = new SHA256Managed();
            var passwordHashData = sha.ComputeHash(TLUtils.Combine(currentSalt.Data, new TLString(_password).Data, currentSalt.Data));
            var passwordHash     = TLString.FromBigEndianData(passwordHashData);

            IsWorking = true;
            MTProtoService.GetPasswordSettingsAsync(passwordHash,
                                                    result => BeginOnUIThread(() =>
            {
                IsWorking = false;

                _passwordBase.CurrentPasswordHash = passwordHash;
                _passwordBase.Settings            = result;

                StateService.RemoveBackEntry = true;
                StateService.Password        = _passwordBase;
                NavigationService.UriFor <PasswordViewModel>().Navigate();
            }),
                                                    error => BeginOnUIThread(() =>
            {
                IsWorking = false;
                if (error.TypeEquals(ErrorType.PASSWORD_HASH_INVALID))
                {
                    MessageBox.Show(AppResources.PasswordInvalidString, AppResources.Error, MessageBoxButton.OK);
                }
                else if (error.CodeEquals(ErrorCode.FLOOD))
                {
                    MessageBox.Show(AppResources.FloodWaitString + Environment.NewLine + "(" + error.Message + ")", AppResources.Error, MessageBoxButton.OK);
                }
                else
                {
                    Execute.ShowDebugMessage("account.checkPassword error " + error);
                }
            }));
        }
示例#17
0
        private static byte[] ComposeCheckPhoneRequest(string phoneNumber)
        {
            TLUtils.WriteLine("--Compose CheckPhone request--");

            // revert documentation order
            var signature        = new byte[] { 0xfb, 0x1d, 0xe5, 0x6f };
            var phoneNumberBytes = Encoding.UTF8.GetBytes(phoneNumber);
            var phoneNumberStr   = TLString.FromBigEndianData(phoneNumberBytes.ToArray());

            TLUtils.WriteLine("Phone");
            TLUtils.WriteLine(BitConverter.ToString(phoneNumberBytes));
            TLUtils.WriteLine("Phone serialized");
            TLUtils.WriteLine(BitConverter.ToString(phoneNumberStr.ToBytes()));

            TLUtils.WriteLine("---------------------------------");

            return(signature
                   .Concat(phoneNumberStr.ToBytes())
                   .ToArray());
        }
示例#18
0
        private static TLString GetEncryptedClientDHInnerData(TLClientDHInnerData clientDHInnerData, WindowsPhone.Tuple <byte[], byte[]> aesParams)
        {
            var random = new Random();
            var client_DH_inner_data = clientDHInnerData.ToBytes();

            var client_DH_inner_dataWithHash = TLUtils.Combine(Utils.ComputeSHA1(client_DH_inner_data), client_DH_inner_data);
            var addedBytesLength             = 16 - (client_DH_inner_dataWithHash.Length % 16);

            if (addedBytesLength > 0 && addedBytesLength < 16)
            {
                var addedBytes = new byte[addedBytesLength];
                random.NextBytes(addedBytes);
                client_DH_inner_dataWithHash = TLUtils.Combine(client_DH_inner_dataWithHash, addedBytes);
                //TLUtils.WriteLine(string.Format("Added {0} bytes", addedBytesLength));
            }

            var aesEncryptClientDHInnerDataWithHash = Utils.AesIge(client_DH_inner_dataWithHash, aesParams.Item1, aesParams.Item2, true);

            return(TLString.FromBigEndianData(aesEncryptClientDHInnerDataWithHash));
        }
示例#19
0
        public static void SetParams(string passcode, bool isSimple, int autolockTimeout)
        {
            var salt         = new byte[256];
            var secureRandom = new RNGCryptoServiceProvider();

            secureRandom.GetBytes(salt);
            var hash           = Telegram.Api.Helpers.Utils.ComputeSHA1(TLUtils.Combine(salt, new TLString(passcode).Data, salt));
            var passcodeParams = new TLPasscodeParams
            {
                Hash            = TLString.FromBigEndianData(hash),
                Salt            = TLString.FromBigEndianData(salt),
                IsSimple        = new TLBool(isSimple),
                AutolockTimeout = new TLInt(autolockTimeout),
                CloseTime       = new TLInt(0),
                Locked          = TLBool.False
            };

            _cachedParams = passcodeParams;
            Save();
        }
示例#20
0
        private void ProcessAcceptedCall(TLPhoneCallAccepted phoneCallAccepted)
        {
            DispatchStateChanged(PhoneCallState.STATE_EXCHANGING_KEYS);

            if (!TLUtils.CheckGaAndGb(phoneCallAccepted.GB.Data, _secretP.Data))
            {
                CallFailed();
                return;
            }


            _authKey = MTProtoService.GetAuthKey(_aOrB, phoneCallAccepted.GB.ToBytes(), _secretP.ToBytes());
            var keyHash        = Utils.ComputeSHA1(_authKey);
            var keyFingerprint = new TLLong(BitConverter.ToInt64(keyHash, 12));

            var peer = new TLInputPhoneCall
            {
                Id         = phoneCallAccepted.Id,
                AccessHash = phoneCallAccepted.AccessHash
            };

            var protocol = new TLPhoneCallProtocol
            {
                Flags        = new TLInt(0),
                UdpP2P       = true,
                UdpReflector = true,
                MinLayer     = new TLInt(CALL_MIN_LAYER),
                MaxLayer     = new TLInt(CALL_MAX_LAYER)
            };

            _mtProtoService.ConfirmCallAsync(peer, TLString.FromBigEndianData(_ga), keyFingerprint, protocol,
                                             result =>
            {
                _call = result;
                InitiateActualEncryptedCall();
            },
                                             error =>
            {
                CallFailed();
            });
        }
示例#21
0
        private void UploadAudioFileAsync(bool isLastPart)
        {
            Execute.BeginOnThreadPool(() =>
            {
                if (!_isPartReady)
                {
                    return;
                }

                _isPartReady = false;

                var uploadablePart = GetUploadablePart(_fileName, _uploadingLength, _uploadableParts.Count, isLastPart);
                if (uploadablePart == null)
                {
                    _isPartReady = true;
                    return;
                }

                _uploadableParts.Add(uploadablePart);
                _uploadingLength += uploadablePart.Count;

                //Execute.BeginOnUIThread(() => VibrateController.Default.Start(TimeSpan.FromSeconds(0.02)));

                if (!isLastPart)
                {
                    var mtProtoService = IoC.Get <IMTProtoService>();
                    mtProtoService.SaveFilePartAsync(_fileId, uploadablePart.FilePart,
                                                     TLString.FromBigEndianData(uploadablePart.Bytes),
                                                     result =>
                    {
                        if (result.Value)
                        {
                            uploadablePart.Status = PartStatus.Processed;
                        }
                    },
                                                     error => Execute.ShowDebugMessage("upload.saveFilePart error " + error));
                }

                _isPartReady = true;
            });
        }
        private bool PutFile(TLLong fileId, TLInt filePart, byte[] bytes)
        {
            var manualResetEvent = new ManualResetEvent(false);
            var result           = false;

            _mtProtoService.SaveFilePartAsync(fileId, filePart, TLString.FromBigEndianData(bytes),
                                              savingResult =>
            {
                result = true;
                manualResetEvent.Set();
            },
                                              error => Execute.BeginOnThreadPool(TimeSpan.FromSeconds(1.0), () =>
            {
                Execute.ShowDebugMessage(string.Format("upload.saveBigFilePart part={0}, count={1} error\n", filePart.Value, bytes.Length) + error);

                manualResetEvent.Set();
            }));

            manualResetEvent.WaitOne();
            return(result);
        }
示例#23
0
        public void SendAudio(AudioEventArgs args)
        {
            Telegram.Logs.Log.Write("DialogDetailsViewModel.SendAudio file_name=" + args.OggFileName);

            if (string.IsNullOrEmpty(args.OggFileName))
            {
                return;
            }

            Telegram.Logs.Log.Write("DialogDetailsViewModel.SendAudio check_disable_feature file_name=" + args.OggFileName);

            var id         = TLLong.Random();
            var accessHash = TLLong.Random();

            var oggFileName = string.Format("audio{0}_{1}.mp3", id, accessHash);
            var wavFileName = Path.GetFileNameWithoutExtension(oggFileName) + ".wav";

            long size = 0;

            using (var storage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                storage.MoveFile(args.OggFileName, oggFileName);
                using (var file = storage.OpenFile(oggFileName, FileMode.Open, FileAccess.Read))
                {
                    size = file.Length;
                }

                var wavStream = args.PcmStream.GetWavAsMemoryStream(16000, 1, 16);
                using (var file = new IsolatedStorageFileStream(wavFileName, FileMode.OpenOrCreate, storage))
                {
                    wavStream.Seek(0, SeekOrigin.Begin);
                    wavStream.CopyTo(file);
                    file.Flush();
                }
            }

            var opus          = new TelegramClient_Opus.WindowsPhoneRuntimeComponent();
            var bytes         = opus.GetWaveform(ApplicationData.Current.LocalFolder.Path + "\\" + oggFileName);
            var resultSamples = bytes.Length;
            var bites2        = new BitArray(5 * bytes.Length);
            var count         = 0;

            for (var i = 0; i < bytes.Length; i++)
            {
                var result = bytes[i];
                var bit1   = result >> 0 & 0x1;
                var bit2   = result >> 1 & 0x1;
                var bit3   = result >> 2 & 0x1;
                var bit4   = result >> 3 & 0x1;
                var bit5   = result >> 4 & 0x1;
                bites2[count]     = Convert.ToBoolean(bit1);
                bites2[count + 1] = Convert.ToBoolean(bit2);
                bites2[count + 2] = Convert.ToBoolean(bit3);
                bites2[count + 3] = Convert.ToBoolean(bit4);
                bites2[count + 4] = Convert.ToBoolean(bit5);
                count             = count + 5;
            }

            var bytesCount    = (resultSamples * 5) / 8 + (((resultSamples * 5) % 8) == 0 ? 0 : 1);
            var waveformBytes = new byte[bytesCount];

            bites2.CopyTo(waveformBytes, 0);
            var waveform = waveformBytes != null?TLString.FromBigEndianData(waveformBytes) : TLString.Empty;

            var audioAttribute = new TLDocumentAttributeAudio46
            {
                Flags    = new TLInt((int)DocumentAttributeAudioFlags.Voice),
                Duration = new TLInt((int)args.Duration)
            };

            if (waveformBytes != null)
            {
                audioAttribute.Waveform = waveform;
            }

            var attributes = new TLVector <TLDocumentAttributeBase>
            {
                audioAttribute
            };

            var document = new TLDocument54
            {
                Id         = id,
                AccessHash = accessHash,
                Date       = TLUtils.DateToUniversalTimeTLInt(MTProtoService.ClientTicksDelta, DateTime.Now),
                //Duration = new TLInt((int)args.Duration),
                MimeType = new TLString("audio/ogg"),
                Size     = new TLInt((int)size),
                Thumb    = new TLPhotoSizeEmpty {
                    Type = TLString.Empty
                },
                DCId       = new TLInt(0),
                Version    = new TLInt(0),
                Attributes = attributes
            };

            var channel   = With as TLChannel;
            var isChannel = channel != null && !channel.IsMegaGroup;

            var media = new TLMessageMediaDocument75 {
                Flags = new TLInt(0), Document = document, Caption = TLString.Empty, IsoFileName = oggFileName, NotListened = !isChannel
            };

            var message = GetMessage(TLString.Empty, media);

            message.NotListened = !isChannel;

            Telegram.Logs.Log.Write(string.Format("DialogDetailsViewModel.SendAudio start sending file_name={0} rnd_id={1}", args.OggFileName, message.RandomId));
            BeginOnUIThread(() =>
            {
                var previousMessage = InsertSendingMessage(message);
                message.NotifyOfPropertyChange(() => message.Media);
                IsEmptyDialog = Items.Count == 0 && (_messages == null || _messages.Count == 0) && LazyItems.Count == 0;

                BeginOnThreadPool(() =>
                                  CacheService.SyncSendingMessage(
                                      message, previousMessage,
                                      m => SendAudioInternal(message, args)));
            });
        }
示例#24
0
        public static TLInputCheckPasswordBase GetCheck(TLString xStr, TLLong srpId, TLString srpB, TLPasswordKdfAlgoBase algoBase)
        {
            var algo = algoBase as TLPasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow;

            if (algo != null)
            {
                if (xStr == null || srpB == null || srpB.Data.Length == 0 || !TLUtils.CheckPrime(algo.P.Data, algo.G.Value))
                {
                    return(new TLInputCheckPasswordEmpty());
                }

                var g       = new BigInteger(1, algo.G.ToBytes().Reverse().ToArray()); // from big-endian to BI (ToBytes - little endian output)
                var g_bytes = GetBigIntegerBytes(g);

                var p       = new BigInteger(1, algo.P.Data);
                var p_bytes = GetBigIntegerBytes(p);

                var k_bytes = Telegram.Api.Helpers.Utils.ComputeSHA256(TLUtils.Combine(p_bytes, g_bytes));
                var k       = new BigInteger(1, k_bytes);

                var x = new BigInteger(1, xStr.Data);

                var a_bytes      = new byte[256];
                var secureRandom = new SecureRandom();
                secureRandom.NextBytes(a_bytes);
                var a = new BigInteger(1, a_bytes);

                var A       = g.ModPow(a, p);
                var A_bytes = GetBigIntegerBytes(A);

                var B = new BigInteger(1, srpB.Data);
                if (B.CompareTo(BigInteger.Zero) <= 0 || B.CompareTo(p) >= 0)
                {
                    return(null);
                }
                var B_bytes = GetBigIntegerBytes(B);

                var u_bytes = Telegram.Api.Helpers.Utils.ComputeSHA256(TLUtils.Combine(A_bytes, B_bytes));
                var u       = new BigInteger(1, u_bytes);
                if (u.CompareTo(BigInteger.Zero) == 0)
                {
                    return(null);
                }

                var B_kgx = B.Subtract(k.Multiply(g.ModPow(x, p)).Mod(p));
                if (B_kgx.CompareTo(BigInteger.Zero) < 0)
                {
                    B_kgx = B_kgx.Add(p);
                }
                if (!TLUtils.CheckGaAndGb(B_kgx, p))
                {
                    return(null);
                }
                var S       = B_kgx.ModPow(a.Add(u.Multiply(x)), p);
                var S_bytes = GetBigIntegerBytes(S);

                var K_bytes = Telegram.Api.Helpers.Utils.ComputeSHA256(S_bytes);

                var p_hash = Telegram.Api.Helpers.Utils.ComputeSHA256(algo.P.Data);
                var g_hash = Telegram.Api.Helpers.Utils.ComputeSHA256(g_bytes);
                for (var i = 0; i < p_hash.Length; i++)
                {
                    p_hash[i] = (byte)(g_hash[i] ^ p_hash[i]);
                }

                var M1 = Telegram.Api.Helpers.Utils.ComputeSHA256(TLUtils.Combine(
                                                                      p_hash,
                                                                      Telegram.Api.Helpers.Utils.ComputeSHA256(algo.Salt1.Data),
                                                                      Telegram.Api.Helpers.Utils.ComputeSHA256(algo.Salt2.Data),
                                                                      A_bytes,
                                                                      B_bytes,
                                                                      K_bytes));

                return(new TLInputCheckPasswordSRP
                {
                    SRPId = srpId,
                    A = TLString.FromBigEndianData(A_bytes),
                    M1 = TLString.FromBigEndianData(M1)
                });
            }

            return(new TLInputCheckPasswordEmpty());
        }
示例#25
0
        public static TLString GetHash(TLString currentSalt, TLString password)
        {
            var passwordHash = Telegram.Api.Helpers.Utils.ComputeSHA256(TLUtils.Combine(currentSalt.Data, password.Data, currentSalt.Data));

            return(TLString.FromBigEndianData(passwordHash));
        }
示例#26
0
        protected TLFileBase GetCdnFile(TLFileCdnRedirect redirect, TLInt offset, TLInt limit, out TLCdnFileReuploadNeeded reuploadNeeded, out TLRPCError er, out bool isCanceled, out bool isTokenInvalid)
        {
            var        manualResetEvent = new ManualResetEvent(false);
            TLFileBase result           = null;
            TLCdnFileReuploadNeeded outReuploadNeeded = null;
            TLRPCError outError          = null;
            var        outIsCanceled     = false;
            var        outIsTokenInvalid = false;

            _mtProtoService.GetCdnFileAsync(redirect.DCId, redirect.FileToken, offset, limit,
                                            cdnFileBase =>
            {
                var cdnFile = cdnFileBase as TLCdnFile;
                if (cdnFile != null)
                {
                    var iv      = GetIV(redirect.EncryptionIV.Data, offset);
                    var counter = offset.Value / 16;
                    iv[15]      = (byte)(counter & 0xFF);
                    iv[14]      = (byte)((counter >> 8) & 0xFF);
                    iv[13]      = (byte)((counter >> 16) & 0xFF);
                    iv[12]      = (byte)((counter >> 24) & 0xFF);

                    var key = redirect.EncryptionKey.Data;

                    var ecount_buf = new byte[0];
                    var num        = 0u;
                    var bytes      = Utils.AES_ctr128_encrypt(cdnFile.Bytes.Data, key, ref iv, ref ecount_buf, ref num);

                    result = new TLFile {
                        Bytes = TLString.FromBigEndianData(bytes)
                    };
                }

                var cdnFileReuploadNeeded = cdnFileBase as TLCdnFileReuploadNeeded;
                if (cdnFileReuploadNeeded != null)
                {
                    outReuploadNeeded = cdnFileReuploadNeeded;
                }

                manualResetEvent.Set();
            },
                                            error =>
            {
                outError = error;

                if (error.CodeEquals(ErrorCode.INTERNAL) ||
                    (error.CodeEquals(ErrorCode.BAD_REQUEST) && (error.TypeEquals(ErrorType.LOCATION_INVALID) || error.TypeEquals(ErrorType.VOLUME_LOC_NOT_FOUND))) ||
                    (error.CodeEquals(ErrorCode.NOT_FOUND) && error.Message != null && error.Message.ToString().StartsWith("Incorrect dhGen")))
                {
                    outIsCanceled = true;

                    manualResetEvent.Set();
                    return;
                }
                if (error.CodeEquals(ErrorCode.BAD_REQUEST) && error.TypeEquals(ErrorType.FILE_TOKEN_INVALID))
                {
                    outIsTokenInvalid = true;

                    manualResetEvent.Set();
                    return;
                }

                int delay;
                lock (_randomRoot)
                {
                    delay = _random.Next(1000, 3000);
                }

                Execute.BeginOnThreadPool(TimeSpan.FromMilliseconds(delay), () => manualResetEvent.Set());
            });

            manualResetEvent.WaitOne();
            reuploadNeeded = outReuploadNeeded;
            er             = outError;
            isCanceled     = outIsCanceled;
            isTokenInvalid = outIsTokenInvalid;

            return(result);
        }
示例#27
0
        public static async Task <Tuple <bool, byte[]> > FillBuffer(IStorageFile file, UploadablePart part)
        {
            try
            {
                if (part.ParentItem.FileNotFound)
                {
                    return(new Tuple <bool, byte[]>(false, null));
                }

                System.Diagnostics.Debug.WriteLine("FillBuffer part=" + part.FilePart);
                using (var inStream = await file.OpenSequentialReadAsync())
                {
                    using (var stream = inStream.AsStreamForRead())
                    //using (var inStream = stream.GetInputStreamAt((ulong) part.Position))
                    {
                        stream.Seek(part.Position, SeekOrigin.Begin);
                        var bytes = new byte[part.Count];

                        stream.Read(bytes, 0, bytes.Length);
                        //using (var reader = new DataReader(inStream))
                        //{
                        //    await reader.LoadAsync((uint) bytes.Length);
                        //    reader.ReadBytes(bytes);
                        //}

                        // encrypting part
                        if (part.ParentItem.Key != null &&
                            part.ParentItem.IV != null)
                        {
                            var key = part.ParentItem.Key;
                            var iv  = part.FilePart.Value == 0 ? part.ParentItem.IV : part.IV;

                            if (iv == null)
                            {
                                return(new Tuple <bool, byte[]>(true, null));
                            }

                            byte[] nextIV;

                            var encryptedBytes = Utils.AesIge(bytes, key.Data, iv.Data, true, out nextIV);
                            bytes = encryptedBytes;

                            var nextPartId = part.FilePart.Value + 1;
                            if (part.ParentItem.Parts.Count > nextPartId)
                            {
                                part.ParentItem.Parts[nextPartId].IV = TLString.FromBigEndianData(nextIV);
                            }
                        }

                        return(new Tuple <bool, byte[]>(true, bytes));
                    }
                }
            }
            catch (FileNotFoundException ex)
            {
                Logs.Log.Write(string.Format("FileUtils.FillBuffer bytes=null position={0} count={1} ex={2}", part.Position, part.Count, ex));
                Execute.ShowDebugMessage("FillBuffer FileNotFoundException\n" + ex);
                return(new Tuple <bool, byte[]>(false, null));
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("FillBuffer ex part=" + part.FilePart);
                Logs.Log.Write(string.Format("FileUtils.FillBuffer bytes=null position={0} count={1} ex={2}", part.Position, part.Count, ex));
                Execute.ShowDebugMessage("FillBuffer Exception\n" + ex);
                return(new Tuple <bool, byte[]>(true, null));
            }
        }
        private void SendVideo(string videoFileName, long duration)
        {
            var chat = Chat as TLEncryptedChat;

            if (chat == null)
            {
                return;
            }

            if (string.IsNullOrEmpty(videoFileName))
            {
                return;
            }

            long size = 0;

            byte[] data;
            using (var storage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (var file = storage.OpenFile(videoFileName, FileMode.Open, FileAccess.Read))
                {
                    size = file.Length;
                    data = new byte[size];
                    file.Read(data, 0, data.Length);
                }
            }

            byte[] thumb;
            using (var storage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (var file = storage.OpenFile(videoFileName + ".jpg", FileMode.Open, FileAccess.Read))
                {
                    thumb = new byte[file.Length];
                    file.Read(thumb, 0, thumb.Length);
                }
            }

            var dcId       = TLInt.Random();
            var id         = TLLong.Random();
            var accessHash = TLLong.Random();

            var fileLocation = new TLEncryptedFile
            {
                Id             = id,
                AccessHash     = accessHash,
                DCId           = dcId,
                Size           = new TLInt((int)size),
                KeyFingerprint = new TLInt(0),
                FileName       = new TLString(""),
                Duration       = new TLInt((int)duration)
            };

            var fileName = String.Format("{0}_{1}_{2}.mp4",
                                         fileLocation.Id,
                                         fileLocation.DCId,
                                         fileLocation.AccessHash);

            using (var store = IsolatedStorageFile.GetUserStoreForApplication())
            {
                store.CopyFile(videoFileName, fileName, true);
                store.DeleteFile(videoFileName);
            }

            var keyIV = GenerateKeyIV();

            int thumbHeight;
            int thumbWidth;

            thumb = ImageUtils.CreateThumb(thumb, Constants.VideoPreviewMaxSize, Constants.VideoPreviewQuality, out thumbHeight, out thumbWidth);

            TLDecryptedMessageMediaVideo decryptedMediaVideo;
            var encryptedChat17 = chat as TLEncryptedChat17;

            if (encryptedChat17 != null)
            {
                decryptedMediaVideo = new TLDecryptedMessageMediaVideo17
                {
                    Thumb    = TLString.FromBigEndianData(thumb),
                    ThumbW   = new TLInt(thumbWidth),
                    ThumbH   = new TLInt(thumbHeight),
                    Duration = new TLInt((int)duration),
                    MimeType = new TLString("video/mp4"),
                    W        = new TLInt(640),
                    H        = new TLInt(480),
                    Size     = new TLInt((int)size),
                    Key      = keyIV.Item1,
                    IV       = keyIV.Item2,

                    File = fileLocation,

                    UploadingProgress = 0.001
                };
            }
            else
            {
                decryptedMediaVideo = new TLDecryptedMessageMediaVideo
                {
                    Thumb    = TLString.FromBigEndianData(thumb),
                    ThumbW   = new TLInt(thumbWidth),
                    ThumbH   = new TLInt(thumbHeight),
                    Duration = new TLInt((int)duration),
                    //MimeType = new TLString("video/mp4"),
                    W    = new TLInt(640),
                    H    = new TLInt(480),
                    Size = new TLInt((int)size),
                    Key  = keyIV.Item1,
                    IV   = keyIV.Item2,

                    File = fileLocation,

                    UploadingProgress = 0.001
                };
            }

            var decryptedTuple = GetDecryptedMessageAndObject(TLString.Empty, decryptedMediaVideo, chat, true);

            Items.Insert(0, decryptedTuple.Item1);
            RaiseScrollToBottom();
            NotifyOfPropertyChange(() => DescriptionVisibility);

            BeginOnThreadPool(() =>
                              CacheService.SyncDecryptedMessage(decryptedTuple.Item1, chat,
                                                                cachedMessage => SendVideoInternal(data, decryptedTuple.Item2)));
        }
示例#29
0
        public void Confirm()
        {
            if (_password == null)
            {
                return;
            }
            if (!CanConfirm)
            {
                return;
            }

            var currentSalt      = _password.CurrentSalt;
            var sha              = new SHA256Managed();
            var passwordHashData = sha.ComputeHash(TLUtils.Combine(currentSalt.Data, new TLString(Code).Data, currentSalt.Data));
            var passwordHash     = TLString.FromBigEndianData(passwordHashData);

            IsWorking = true;
#if LOG_REGISTRATION
            TLUtils.WriteLog("auth.checkPassword");
#endif
            MTProtoService.CheckPasswordAsync(passwordHash,
                                              auth => BeginOnUIThread(() =>
            {
#if LOG_REGISTRATION
                TLUtils.WriteLog("auth.checkPassword result " + auth);
                TLUtils.WriteLog("TLUtils.IsLogEnabled=false");
#endif

                TLUtils.IsLogEnabled = false;
                TLUtils.LogItems.Clear();

                var result = MessageBox.Show(
                    AppResources.ConfirmPushMessage,
                    AppResources.ConfirmPushTitle,
                    MessageBoxButton.OKCancel);

                if (result != MessageBoxResult.OK)
                {
                    StateService.GetNotifySettingsAsync(settings =>
                    {
                        var s                   = settings ?? new Settings();
                        s.ContactAlert          = false;
                        s.ContactMessagePreview = true;
                        s.ContactSound          = StateService.Sounds[0];
                        s.GroupAlert            = false;
                        s.GroupMessagePreview   = true;
                        s.GroupSound            = StateService.Sounds[0];

                        s.InAppMessagePreview = true;
                        s.InAppSound          = true;
                        s.InAppVibration      = true;

                        StateService.SaveNotifySettingsAsync(s);
                    });

                    MTProtoService.UpdateNotifySettingsAsync(
                        new TLInputNotifyUsers(),
                        new TLInputPeerNotifySettings
                    {
                        EventsMask   = new TLInt(1),
                        MuteUntil    = new TLInt(int.MaxValue),
                        ShowPreviews = new TLBool(true),
                        Sound        = new TLString(StateService.Sounds[0])
                    },
                        r => { });

                    MTProtoService.UpdateNotifySettingsAsync(
                        new TLInputNotifyChats(),
                        new TLInputPeerNotifySettings
                    {
                        EventsMask   = new TLInt(1),
                        MuteUntil    = new TLInt(int.MaxValue),
                        ShowPreviews = new TLBool(true),
                        Sound        = new TLString(StateService.Sounds[0])
                    },
                        r => { });
                }
                else
                {
                    StateService.GetNotifySettingsAsync(settings =>
                    {
                        var s                   = settings ?? new Settings();
                        s.ContactAlert          = true;
                        s.ContactMessagePreview = true;
                        s.ContactSound          = StateService.Sounds[0];
                        s.GroupAlert            = true;
                        s.GroupMessagePreview   = true;
                        s.GroupSound            = StateService.Sounds[0];

                        s.InAppMessagePreview = true;
                        s.InAppSound          = true;
                        s.InAppVibration      = true;

                        StateService.SaveNotifySettingsAsync(s);
                    });

                    MTProtoService.UpdateNotifySettingsAsync(
                        new TLInputNotifyUsers(),
                        new TLInputPeerNotifySettings
                    {
                        EventsMask   = new TLInt(1),
                        MuteUntil    = new TLInt(0),
                        ShowPreviews = new TLBool(true),
                        Sound        = new TLString(StateService.Sounds[0])
                    },
                        r => { });

                    MTProtoService.UpdateNotifySettingsAsync(
                        new TLInputNotifyChats(),
                        new TLInputPeerNotifySettings
                    {
                        EventsMask   = new TLInt(1),
                        MuteUntil    = new TLInt(0),
                        ShowPreviews = new TLBool(true),
                        Sound        = new TLString(StateService.Sounds[0])
                    },
                        r => { });
                }

                MTProtoService.SetInitState();
                StateService.CurrentUserId        = auth.User.Index;
                StateService.ClearNavigationStack = true;
                StateService.FirstRun             = true;
                SettingsHelper.SetValue(Constants.IsAuthorizedKey, true);
                NavigationService.UriFor <ShellViewModel>().Navigate();
                IsWorking = false;
            }),
                                              error => BeginOnUIThread(() =>
            {
#if LOG_REGISTRATION
                TLUtils.WriteLog("auth.checkPassword error " + error);
#endif
                IsWorking = false;
                if (error.TypeEquals(ErrorType.PASSWORD_HASH_INVALID))
                {
                    MessageBox.Show(AppResources.PasswordInvalidString, AppResources.Error, MessageBoxButton.OK);
                }
                else if (error.CodeEquals(ErrorCode.FLOOD))
                {
                    MessageBox.Show(AppResources.FloodWaitString + Environment.NewLine + "(" + error.Message + ")", AppResources.Error, MessageBoxButton.OK);
                }
                else
                {
                    Execute.ShowDebugMessage("account.checkPassword error " + error);
                }
            }));
        }
示例#30
0
        public void InitAsync(Action <WindowsPhone.Tuple <byte[], TLLong, TLLong> > callback, Action <TLRPCError> faultCallback = null)
        {
            var authTime = Stopwatch.StartNew();
            var newNonce = TLInt256.Random();

#if LOG_REGISTRATION
            TLUtils.WriteLog("Start ReqPQ");
#endif
            var nonce = TLInt128.Random();
            ReqPQAsync(nonce,
                       resPQ =>
            {
                GetServerPublicKeyAsync(_activeTransport.DCId, resPQ.ServerPublicKeyFingerprints,
                                        (index, publicKey) =>
                {
                    if (index < 0 || string.IsNullOrEmpty(publicKey))
                    {
                        var error = new TLRPCError {
                            Code = new TLInt(404), Message = new TLString("unknown public key")
                        };
#if LOG_REGISTRATION
                        TLUtils.WriteLog("Stop ReqPQ with error " + error);
#endif

                        if (faultCallback != null)
                        {
                            faultCallback(error);
                        }
                        TLUtils.WriteLine(error.ToString());
                    }

                    var serverNonce = resPQ.ServerNonce;
                    if (!TLUtils.ByteArraysEqual(nonce.Value, resPQ.Nonce.Value))
                    {
                        var error = new TLRPCError {
                            Code = new TLInt(404), Message = new TLString("incorrect nonce")
                        };
#if LOG_REGISTRATION
                        TLUtils.WriteLog("Stop ReqPQ with error " + error);
#endif

                        if (faultCallback != null)
                        {
                            faultCallback(error);
                        }
                        TLUtils.WriteLine(error.ToString());
                    }

#if LOG_REGISTRATION
                    TLUtils.WriteLog("Stop ReqPQ");
#endif
                    TimeSpan calcTime;
                    WindowsPhone.Tuple <ulong, ulong> pqPair;
                    var innerData          = GetInnerData(new TLInt(TLUtils.GetProtocolDCId(_activeTransport.DCId, false, Constants.IsTestServer)), resPQ, newNonce, out calcTime, out pqPair);
                    var encryptedInnerData = GetEncryptedInnerData(innerData, publicKey);

#if LOG_REGISTRATION
                    var pq          = BitConverter.ToUInt64(resPQ.PQ.Data.Reverse().ToArray(), 0);
                    var logPQString = new StringBuilder();
                    logPQString.AppendLine("PQ Counters");
                    logPQString.AppendLine();
                    logPQString.AppendLine("pq: " + pq);
                    logPQString.AppendLine("p: " + pqPair.Item1);
                    logPQString.AppendLine("q: " + pqPair.Item2);
                    logPQString.AppendLine("encrypted_data length: " + encryptedInnerData.Data.Length);
                    TLUtils.WriteLog(logPQString.ToString());
                    TLUtils.WriteLog("Start ReqDHParams");
#endif
                    ReqDHParamsAsync(
                        resPQ.Nonce,
                        resPQ.ServerNonce,
                        innerData.P,
                        innerData.Q,
                        resPQ.ServerPublicKeyFingerprints[0],
                        encryptedInnerData,
                        serverDHParams =>
                    {
                        if (!TLUtils.ByteArraysEqual(nonce.Value, serverDHParams.Nonce.Value))
                        {
                            var error = new TLRPCError {
                                Code = new TLInt(404), Message = new TLString("incorrect nonce")
                            };
#if LOG_REGISTRATION
                            TLUtils.WriteLog("Stop ReqDHParams with error " + error);
#endif

                            if (faultCallback != null)
                            {
                                faultCallback(error);
                            }
                            TLUtils.WriteLine(error.ToString());
                        }
                        if (!TLUtils.ByteArraysEqual(serverNonce.Value, serverDHParams.ServerNonce.Value))
                        {
                            var error = new TLRPCError {
                                Code = new TLInt(404), Message = new TLString("incorrect server_nonce")
                            };
#if LOG_REGISTRATION
                            TLUtils.WriteLog("Stop ReqDHParams with error " + error);
#endif

                            if (faultCallback != null)
                            {
                                faultCallback(error);
                            }
                            TLUtils.WriteLine(error.ToString());
                        }

#if LOG_REGISTRATION
                        TLUtils.WriteLog("Stop ReqDHParams");
#endif
                        var random = new SecureRandom();

                        var serverDHParamsOk = serverDHParams as TLServerDHParamsOk;
                        if (serverDHParamsOk == null)
                        {
                            var error = new TLRPCError {
                                Code = new TLInt(404), Message = new TLString("Incorrect serverDHParams " + serverDHParams.GetType())
                            };
                            if (faultCallback != null)
                            {
                                faultCallback(error);
                            }
                            TLUtils.WriteLine(error.ToString());
#if LOG_REGISTRATION
                            TLUtils.WriteLog("ServerDHParams " + serverDHParams);
#endif
                            return;
                        }

                        var aesParams = GetAesKeyIV(resPQ.ServerNonce.ToBytes(), newNonce.ToBytes());

                        var decryptedAnswerWithHash = Utils.AesIge(serverDHParamsOk.EncryptedAnswer.Data, aesParams.Item1, aesParams.Item2, false);

                        var position          = 0;
                        var serverDHInnerData = (TLServerDHInnerData) new TLServerDHInnerData().FromBytes(decryptedAnswerWithHash.Skip(20).ToArray(), ref position);

                        var sha1 = Utils.ComputeSHA1(serverDHInnerData.ToBytes());
                        if (!TLUtils.ByteArraysEqual(sha1, decryptedAnswerWithHash.Take(20).ToArray()))
                        {
                            var error = new TLRPCError {
                                Code = new TLInt(404), Message = new TLString("incorrect sha1 TLServerDHInnerData")
                            };
#if LOG_REGISTRATION
                            TLUtils.WriteLog("Stop ReqDHParams with error " + error);
#endif

                            if (faultCallback != null)
                            {
                                faultCallback(error);
                            }
                            TLUtils.WriteLine(error.ToString());
                        }

                        if (!TLUtils.CheckPrime(serverDHInnerData.DHPrime.Data, serverDHInnerData.G.Value))
                        {
                            var error = new TLRPCError {
                                Code = new TLInt(404), Message = new TLString("incorrect (p, q) pair")
                            };
#if LOG_REGISTRATION
                            TLUtils.WriteLog("Stop ReqDHParams with error " + error);
#endif

                            if (faultCallback != null)
                            {
                                faultCallback(error);
                            }
                            TLUtils.WriteLine(error.ToString());
                        }

                        if (!TLUtils.CheckGaAndGb(serverDHInnerData.GA.Data, serverDHInnerData.DHPrime.Data))
                        {
                            var error = new TLRPCError {
                                Code = new TLInt(404), Message = new TLString("incorrect g_a")
                            };
#if LOG_REGISTRATION
                            TLUtils.WriteLog("Stop ReqDHParams with error " + error);
#endif

                            if (faultCallback != null)
                            {
                                faultCallback(error);
                            }
                            TLUtils.WriteLine(error.ToString());
                        }

                        var bBytes = new byte[256];             //big endian B
                        random.NextBytes(bBytes);

                        var gbBytes = GetGB(bBytes, serverDHInnerData.G, serverDHInnerData.DHPrime);

                        var clientDHInnerData = new TLClientDHInnerData
                        {
                            Nonce       = resPQ.Nonce,
                            ServerNonce = resPQ.ServerNonce,
                            RetryId     = new TLLong(0),
                            GB          = TLString.FromBigEndianData(gbBytes)
                        };

                        var encryptedClientDHInnerData = GetEncryptedClientDHInnerData(clientDHInnerData, aesParams);
#if LOG_REGISTRATION
                        TLUtils.WriteLog("Start SetClientDHParams");
#endif
                        SetClientDHParamsAsync(resPQ.Nonce, resPQ.ServerNonce, encryptedClientDHInnerData,
                                               dhGen =>
                        {
                            if (!TLUtils.ByteArraysEqual(nonce.Value, dhGen.Nonce.Value))
                            {
                                var error = new TLRPCError {
                                    Code = new TLInt(404), Message = new TLString("incorrect nonce")
                                };
#if LOG_REGISTRATION
                                TLUtils.WriteLog("Stop SetClientDHParams with error " + error);
#endif

                                if (faultCallback != null)
                                {
                                    faultCallback(error);
                                }
                                TLUtils.WriteLine(error.ToString());
                            }
                            if (!TLUtils.ByteArraysEqual(serverNonce.Value, dhGen.ServerNonce.Value))
                            {
                                var error = new TLRPCError {
                                    Code = new TLInt(404), Message = new TLString("incorrect server_nonce")
                                };
#if LOG_REGISTRATION
                                TLUtils.WriteLog("Stop SetClientDHParams with error " + error);
#endif

                                if (faultCallback != null)
                                {
                                    faultCallback(error);
                                }
                                TLUtils.WriteLine(error.ToString());
                            }

                            var dhGenOk = dhGen as TLDHGenOk;
                            if (dhGenOk == null)
                            {
                                var error = new TLRPCError {
                                    Code = new TLInt(404), Message = new TLString("Incorrect dhGen " + dhGen.GetType())
                                };
                                if (faultCallback != null)
                                {
                                    faultCallback(error);
                                }
                                TLUtils.WriteLine(error.ToString());
#if LOG_REGISTRATION
                                TLUtils.WriteLog("DHGen result " + serverDHParams);
#endif
                                return;
                            }


                            _authTimeElapsed = authTime.Elapsed;
#if LOG_REGISTRATION
                            TLUtils.WriteLog("Stop SetClientDHParams");
#endif
                            var getKeyTimer = Stopwatch.StartNew();
                            var authKey     = GetAuthKey(bBytes, serverDHInnerData.GA.ToBytes(), serverDHInnerData.DHPrime.ToBytes());

                            var logCountersString = new StringBuilder();

                            logCountersString.AppendLine("Auth Counters");
                            logCountersString.AppendLine();
                            logCountersString.AppendLine("pq factorization time: " + calcTime);
                            logCountersString.AppendLine("calc auth key time: " + getKeyTimer.Elapsed);
                            logCountersString.AppendLine("auth time: " + _authTimeElapsed);
#if LOG_REGISTRATION
                            TLUtils.WriteLog(logCountersString.ToString());
#endif
                            //newNonce - little endian
                            //authResponse.ServerNonce - little endian
                            var salt      = GetSalt(newNonce.ToBytes(), resPQ.ServerNonce.ToBytes());
                            var sessionId = new byte[8];
                            random.NextBytes(sessionId);

                            TLUtils.WriteLine("Salt " + BitConverter.ToInt64(salt, 0) + " (" + BitConverter.ToString(salt) + ")");
                            TLUtils.WriteLine("Session id " + BitConverter.ToInt64(sessionId, 0) + " (" + BitConverter.ToString(sessionId) + ")");

                            callback(new WindowsPhone.Tuple <byte[], TLLong, TLLong>(authKey, new TLLong(BitConverter.ToInt64(salt, 0)), new TLLong(BitConverter.ToInt64(sessionId, 0))));
                        },
                                               error =>
                        {
#if LOG_REGISTRATION
                            TLUtils.WriteLog("Stop SetClientDHParams with error " + error.ToString());
#endif
                            if (faultCallback != null)
                            {
                                faultCallback(error);
                            }
                            TLUtils.WriteLine(error.ToString());
                        });
                    },
                        error =>
                    {
#if LOG_REGISTRATION
                        TLUtils.WriteLog("Stop ReqDHParams with error " + error.ToString());
#endif
                        if (faultCallback != null)
                        {
                            faultCallback(error);
                        }
                        TLUtils.WriteLine(error.ToString());
                    });
                });
            },
                       error =>
            {
#if LOG_REGISTRATION
                TLUtils.WriteLog("Stop ReqPQ with error " + error.ToString());
#endif
                if (faultCallback != null)
                {
                    faultCallback(error);
                }
                TLUtils.WriteLine(error.ToString());
            });
        }