You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
105 lines
2.3 KiB
105 lines
2.3 KiB
// Package exchange contains Telegram key exchange algorithm flows. |
|
// See https://core.telegram.org/mtproto/auth_key. |
|
package exchange |
|
|
|
import ( |
|
"io" |
|
"time" |
|
|
|
"go.uber.org/zap" |
|
|
|
"github.com/gotd/td/clock" |
|
"github.com/gotd/td/internal/crypto" |
|
"github.com/gotd/td/internal/proto" |
|
"github.com/gotd/td/transport" |
|
) |
|
|
|
// DefaultTimeout is default WithTimeout parameter value. |
|
const DefaultTimeout = 1 * time.Minute |
|
|
|
// Exchanger is builder for key exchangers. |
|
type Exchanger struct { |
|
conn transport.Conn |
|
|
|
clock clock.Clock |
|
rand io.Reader |
|
log *zap.Logger |
|
timeout time.Duration |
|
dc int |
|
} |
|
|
|
// WithClock sets exchange flow clock. |
|
func (e Exchanger) WithClock(c clock.Clock) Exchanger { |
|
e.clock = c |
|
return e |
|
} |
|
|
|
// WithRand sets exchange flow random source. |
|
func (e Exchanger) WithRand(reader io.Reader) Exchanger { |
|
e.rand = reader |
|
return e |
|
} |
|
|
|
// WithLogger sets exchange flow logger. |
|
func (e Exchanger) WithLogger(log *zap.Logger) Exchanger { |
|
e.log = log |
|
return e |
|
} |
|
|
|
// WithTimeout sets write/read deadline of every exchange request. |
|
func (e Exchanger) WithTimeout(timeout time.Duration) Exchanger { |
|
e.timeout = timeout |
|
return e |
|
} |
|
|
|
// NewExchanger creates new Exchanger. |
|
func NewExchanger(conn transport.Conn, dc int) Exchanger { |
|
return Exchanger{ |
|
conn: conn, |
|
|
|
clock: clock.System, |
|
rand: crypto.DefaultRand(), |
|
log: zap.NewNop(), |
|
timeout: DefaultTimeout, |
|
dc: dc, |
|
} |
|
} |
|
|
|
func (e Exchanger) unencryptedWriter(input, output proto.MessageType) unencryptedWriter { |
|
return unencryptedWriter{ |
|
clock: e.clock, |
|
conn: e.conn, |
|
timeout: e.timeout, |
|
input: input, |
|
output: output, |
|
} |
|
} |
|
|
|
// Client creates new ClientExchange using parameters from Exchanger. |
|
func (e Exchanger) Client(keys []PublicKey) ClientExchange { |
|
return ClientExchange{ |
|
unencryptedWriter: e.unencryptedWriter( |
|
proto.MessageServerResponse, |
|
proto.MessageFromClient, |
|
), |
|
rand: e.rand, |
|
log: e.log, |
|
keys: keys, |
|
dc: e.dc, |
|
} |
|
} |
|
|
|
// Server creates new ServerExchange using parameters from Exchanger. |
|
func (e Exchanger) Server(key PrivateKey) ServerExchange { |
|
return ServerExchange{ |
|
unencryptedWriter: e.unencryptedWriter( |
|
proto.MessageFromClient, |
|
proto.MessageServerResponse, |
|
), |
|
rand: e.rand, |
|
log: e.log, |
|
rng: TestServerRNG{rand: e.rand}, |
|
key: key, |
|
dc: e.dc, |
|
} |
|
}
|
|
|