/// <summary> /// Генерация ключа авторизации /// </summary> /// <returns></returns> private bool GenerateAuthKey(string address, int port) { using (var connection = new TcpConnection(address, port, _formatter)) { connection.Connect(true); var pns = new PlainMtProtoSession(connection); _nonce = BigInteger.GenerateRandom(128); var reqpq = new Combinator("req_pq", _nonce); RpcAnswer result = pns.RpcCall(reqpq, "resPQ nonce:int128 server_nonce:int128 pq:string server_public_key_fingerprints:Vector long = ResPQ"); if (!result.Success) throw new Exception(result.Error.ToString()); Combinator reqDhParams = ProcessPqAnswer(result.Combinator); result = pns.RpcCall(reqDhParams, "server_DH_params_ok nonce:int128 server_nonce:int128 encrypted_answer:string = Server_DH_Params", "server_DH_params_fail nonce:int128 server_nonce:int128 new_nonce_hash:int128 = Server_DH_Params"); if (result.Combinator.Name == "server_DH_params_ok") { Combinator serverDhInnerData = ProcessDhParams(result.Combinator); Combinator setClientDhParams = SetClientDhParams(serverDhInnerData); result = pns.RpcCall(setClientDhParams, "dh_gen_ok nonce:int128 server_nonce:int128 new_nonce_hash1:int128 = Set_client_DH_params_answer", "dh_gen_retry nonce:int128 server_nonce:int128 new_nonce_hash2:int128 = Set_client_DH_params_answer", "dh_gen_fail nonce:int128 server_nonce:int128 new_nonce_hash3:int128 = Set_client_DH_params_answer"); Thread.Sleep(100); switch (result.Combinator.Name) { case "dh_gen_ok": InitialSalt = CalculateInitialSalt(_newNonce, _serverNonce); // Проверим new_nonce_hash1 bool res = CheckNewNonceHash(result.Combinator.Get<BigInteger>("new_nonce_hash1"), 1); return res; case "dh_gen_retry": // HACK: ретри не реализован case "dh_gen_fail": return false; default: return false; } } return false; } }
public Provider(ApiSchema schema, string address, int port, string phone, ITelegramPersist persist) { _address = address; _port = port; _phone = phone; _persist = persist; _formatter = new Formatter(); Combinator.Setup(schema, _formatter); _settings = LoadSettings(); _connection = new TcpConnection(_address, _port, _formatter); }
public PlainMtProtoSession(TcpConnection connection) { _connection = connection; _packetNumber = 0; }