// Package exchange contains Telegram key exchange algorithm flows. // See https://core.telegram.org/mtproto/auth_key.
package exchange import ( ) // DefaultTimeout is default WithTimeout parameter value. const DefaultTimeout = 1 * time.Minute // ExchangeMode controls type of generated auth key. type ExchangeMode int const ( // ExchangeModePermanent creates permanent authorization key. ExchangeModePermanent ExchangeMode = iota // ExchangeModeTemporary creates temporary authorization key. ExchangeModeTemporary ) // Exchanger is builder for key exchangers. type Exchanger struct { conn transport.Conn clock clock.Clock rand io.Reader log log.Helper timeout time.Duration dc int // mode/expires define auth key type produced by client exchange. mode ExchangeMode expires int } // WithClock sets exchange flow clock. func ( Exchanger) ( clock.Clock) Exchanger { .clock = return } // WithRand sets exchange flow random source. func ( Exchanger) ( io.Reader) Exchanger { .rand = return } // WithLogger sets exchange flow logger. func ( Exchanger) ( log.Logger) Exchanger { .log = log.For() return } // WithTimeout sets write/read deadline of every exchange request. func ( Exchanger) ( time.Duration) Exchanger { .timeout = return } // WithTempMode configures temporary authorization key exchange. // // expiresIn is temporary key lifetime in seconds. func ( Exchanger) ( int) Exchanger { // Switching mode changes only client flow payload type; server flow remains // backward-compatible and accepts both variants. .mode = ExchangeModeTemporary .expires = return } // NewExchanger creates new Exchanger. func ( transport.Conn, int) Exchanger { return Exchanger{ conn: , clock: clock.System, rand: crypto.DefaultRand(), log: log.For(nil), timeout: DefaultTimeout, dc: , // Preserve old behavior by default: generate permanent key unless // caller explicitly requests temporary mode. mode: ExchangeModePermanent, } } func ( Exchanger) (, proto.MessageType) unencryptedWriter { return unencryptedWriter{ clock: .clock, conn: .conn, timeout: .timeout, input: , output: , } } // Client creates new ClientExchange using parameters from Exchanger. func ( Exchanger) ( []PublicKey) ClientExchange { return ClientExchange{ unencryptedWriter: .unencryptedWriter( proto.MessageServerResponse, proto.MessageFromClient, ), rand: .rand, log: .log, keys: , dc: .dc, mode: .mode, expiresIn: .expires, } } // Server creates new ServerExchange using parameters from Exchanger. func ( Exchanger) ( PrivateKey) ServerExchange { return ServerExchange{ unencryptedWriter: .unencryptedWriter( proto.MessageFromClient, proto.MessageServerResponse, ), rand: .rand, log: .log, rng: TestServerRNG{rand: .rand}, key: , dc: .dc, } }