-
-
Notifications
You must be signed in to change notification settings - Fork 134
/
flow.go
102 lines (87 loc) · 2.2 KB
/
flow.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Package exchange contains Telegram key exchange algorithm flows.
// See https://core.telegram.org/mtproto/auth_key.
package exchange
import (
"crypto/rand"
"crypto/rsa"
"io"
"time"
"go.uber.org/zap"
"github.com/gotd/td/clock"
"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
}
// 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) Exchanger {
return Exchanger{
conn: conn,
clock: clock.System,
rand: rand.Reader,
log: zap.NewNop(),
timeout: DefaultTimeout,
}
}
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 []*rsa.PublicKey) ClientExchange {
return ClientExchange{
unencryptedWriter: e.unencryptedWriter(
proto.MessageServerResponse,
proto.MessageFromClient,
),
rand: e.rand,
log: e.log,
keys: keys,
}
}
// Server creates new ServerExchange using parameters from Exchanger.
func (e Exchanger) Server(key *rsa.PrivateKey) ServerExchange {
return ServerExchange{
unencryptedWriter: e.unencryptedWriter(
proto.MessageFromClient,
proto.MessageServerResponse,
),
rand: e.rand,
log: e.log,
rng: TestServerRNG{rand: e.rand},
key: key,
}
}