1
2
3
4
5 package tls
6
7 import (
8 "context"
9 "errors"
10 "fmt"
11 )
12
13
14
15 type QUICEncryptionLevel int
16
17 const (
18 QUICEncryptionLevelInitial = QUICEncryptionLevel(iota)
19 QUICEncryptionLevelEarly
20 QUICEncryptionLevelHandshake
21 QUICEncryptionLevelApplication
22 )
23
24 func (l QUICEncryptionLevel) String() string {
25 switch l {
26 case QUICEncryptionLevelInitial:
27 return "Initial"
28 case QUICEncryptionLevelEarly:
29 return "Early"
30 case QUICEncryptionLevelHandshake:
31 return "Handshake"
32 case QUICEncryptionLevelApplication:
33 return "Application"
34 default:
35 return fmt.Sprintf("QUICEncryptionLevel(%v)", int(l))
36 }
37 }
38
39
40
41
42
43 type QUICConn struct {
44 conn *Conn
45
46 sessionTicketSent bool
47 }
48
49
50 type QUICConfig struct {
51 TLSConfig *Config
52 }
53
54
55 type QUICEventKind int
56
57 const (
58
59 QUICNoEvent QUICEventKind = iota
60
61
62
63
64
65
66
67 QUICSetReadSecret
68 QUICSetWriteSecret
69
70
71
72 QUICWriteData
73
74
75
76 QUICTransportParameters
77
78
79
80
81
82
83
84
85 QUICTransportParametersRequired
86
87
88
89
90 QUICRejectedEarlyData
91
92
93 QUICHandshakeDone
94 )
95
96
97
98
99
100 type QUICEvent struct {
101 Kind QUICEventKind
102
103
104 Level QUICEncryptionLevel
105
106
107
108 Data []byte
109
110
111 Suite uint16
112 }
113
114 type quicState struct {
115 events []QUICEvent
116 nextEvent int
117
118
119
120
121
122 eventArr [8]QUICEvent
123
124 started bool
125 signalc chan struct{}
126 blockedc chan struct{}
127 cancelc <-chan struct{}
128 cancel context.CancelFunc
129
130
131
132
133 readbuf []byte
134
135 transportParams []byte
136 }
137
138
139
140
141
142 func QUICClient(config *QUICConfig) *QUICConn {
143 return newQUICConn(Client(nil, config.TLSConfig))
144 }
145
146
147
148
149
150 func QUICServer(config *QUICConfig) *QUICConn {
151 return newQUICConn(Server(nil, config.TLSConfig))
152 }
153
154 func newQUICConn(conn *Conn) *QUICConn {
155 conn.quic = &quicState{
156 signalc: make(chan struct{}),
157 blockedc: make(chan struct{}),
158 }
159 conn.quic.events = conn.quic.eventArr[:0]
160 return &QUICConn{
161 conn: conn,
162 }
163 }
164
165
166
167
168
169 func (q *QUICConn) Start(ctx context.Context) error {
170 if q.conn.quic.started {
171 return quicError(errors.New("tls: Start called more than once"))
172 }
173 q.conn.quic.started = true
174 if q.conn.config.MinVersion < VersionTLS13 {
175 return quicError(errors.New("tls: Config MinVersion must be at least TLS 1.13"))
176 }
177 go q.conn.HandshakeContext(ctx)
178 if _, ok := <-q.conn.quic.blockedc; !ok {
179 return q.conn.handshakeErr
180 }
181 return nil
182 }
183
184
185
186 func (q *QUICConn) NextEvent() QUICEvent {
187 qs := q.conn.quic
188 if last := qs.nextEvent - 1; last >= 0 && len(qs.events[last].Data) > 0 {
189
190
191 qs.events[last].Data[0] = 0
192 }
193 if qs.nextEvent >= len(qs.events) {
194 qs.events = qs.events[:0]
195 qs.nextEvent = 0
196 return QUICEvent{Kind: QUICNoEvent}
197 }
198 e := qs.events[qs.nextEvent]
199 qs.events[qs.nextEvent] = QUICEvent{}
200 qs.nextEvent++
201 return e
202 }
203
204
205 func (q *QUICConn) Close() error {
206 if q.conn.quic.cancel == nil {
207 return nil
208 }
209 q.conn.quic.cancel()
210 for range q.conn.quic.blockedc {
211
212 }
213 return q.conn.handshakeErr
214 }
215
216
217
218 func (q *QUICConn) HandleData(level QUICEncryptionLevel, data []byte) error {
219 c := q.conn
220 if c.in.level != level {
221 return quicError(c.in.setErrorLocked(errors.New("tls: handshake data received at wrong level")))
222 }
223 c.quic.readbuf = data
224 <-c.quic.signalc
225 _, ok := <-c.quic.blockedc
226 if ok {
227
228 return nil
229 }
230
231 c.handshakeMutex.Lock()
232 defer c.handshakeMutex.Unlock()
233 c.hand.Write(c.quic.readbuf)
234 c.quic.readbuf = nil
235 for q.conn.hand.Len() >= 4 && q.conn.handshakeErr == nil {
236 b := q.conn.hand.Bytes()
237 n := int(b[1])<<16 | int(b[2])<<8 | int(b[3])
238 if n > maxHandshake {
239 q.conn.handshakeErr = fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake)
240 break
241 }
242 if len(b) < 4+n {
243 return nil
244 }
245 if err := q.conn.handlePostHandshakeMessage(); err != nil {
246 q.conn.handshakeErr = err
247 }
248 }
249 if q.conn.handshakeErr != nil {
250 return quicError(q.conn.handshakeErr)
251 }
252 return nil
253 }
254
255 type QUICSessionTicketOptions struct {
256
257 EarlyData bool
258 }
259
260
261
262
263 func (q *QUICConn) SendSessionTicket(opts QUICSessionTicketOptions) error {
264 c := q.conn
265 if !c.isHandshakeComplete.Load() {
266 return quicError(errors.New("tls: SendSessionTicket called before handshake completed"))
267 }
268 if c.isClient {
269 return quicError(errors.New("tls: SendSessionTicket called on the client"))
270 }
271 if q.sessionTicketSent {
272 return quicError(errors.New("tls: SendSessionTicket called multiple times"))
273 }
274 q.sessionTicketSent = true
275 return quicError(c.sendSessionTicket(opts.EarlyData))
276 }
277
278
279 func (q *QUICConn) ConnectionState() ConnectionState {
280 return q.conn.ConnectionState()
281 }
282
283
284
285
286
287 func (q *QUICConn) SetTransportParameters(params []byte) {
288 if params == nil {
289 params = []byte{}
290 }
291 q.conn.quic.transportParams = params
292 if q.conn.quic.started {
293 <-q.conn.quic.signalc
294 <-q.conn.quic.blockedc
295 }
296 }
297
298
299
300 func quicError(err error) error {
301 if err == nil {
302 return nil
303 }
304 var ae AlertError
305 if errors.As(err, &ae) {
306 return err
307 }
308 var a alert
309 if !errors.As(err, &a) {
310 a = alertInternalError
311 }
312
313
314 return fmt.Errorf("%w%.0w", err, AlertError(a))
315 }
316
317 func (c *Conn) quicReadHandshakeBytes(n int) error {
318 for c.hand.Len() < n {
319 if err := c.quicWaitForSignal(); err != nil {
320 return err
321 }
322 }
323 return nil
324 }
325
326 func (c *Conn) quicSetReadSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
327 c.quic.events = append(c.quic.events, QUICEvent{
328 Kind: QUICSetReadSecret,
329 Level: level,
330 Suite: suite,
331 Data: secret,
332 })
333 }
334
335 func (c *Conn) quicSetWriteSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
336 c.quic.events = append(c.quic.events, QUICEvent{
337 Kind: QUICSetWriteSecret,
338 Level: level,
339 Suite: suite,
340 Data: secret,
341 })
342 }
343
344 func (c *Conn) quicWriteCryptoData(level QUICEncryptionLevel, data []byte) {
345 var last *QUICEvent
346 if len(c.quic.events) > 0 {
347 last = &c.quic.events[len(c.quic.events)-1]
348 }
349 if last == nil || last.Kind != QUICWriteData || last.Level != level {
350 c.quic.events = append(c.quic.events, QUICEvent{
351 Kind: QUICWriteData,
352 Level: level,
353 })
354 last = &c.quic.events[len(c.quic.events)-1]
355 }
356 last.Data = append(last.Data, data...)
357 }
358
359 func (c *Conn) quicSetTransportParameters(params []byte) {
360 c.quic.events = append(c.quic.events, QUICEvent{
361 Kind: QUICTransportParameters,
362 Data: params,
363 })
364 }
365
366 func (c *Conn) quicGetTransportParameters() ([]byte, error) {
367 if c.quic.transportParams == nil {
368 c.quic.events = append(c.quic.events, QUICEvent{
369 Kind: QUICTransportParametersRequired,
370 })
371 }
372 for c.quic.transportParams == nil {
373 if err := c.quicWaitForSignal(); err != nil {
374 return nil, err
375 }
376 }
377 return c.quic.transportParams, nil
378 }
379
380 func (c *Conn) quicHandshakeComplete() {
381 c.quic.events = append(c.quic.events, QUICEvent{
382 Kind: QUICHandshakeDone,
383 })
384 }
385
386 func (c *Conn) quicRejectedEarlyData() {
387 c.quic.events = append(c.quic.events, QUICEvent{
388 Kind: QUICRejectedEarlyData,
389 })
390 }
391
392
393
394
395
396
397 func (c *Conn) quicWaitForSignal() error {
398
399
400 c.handshakeMutex.Unlock()
401 defer c.handshakeMutex.Lock()
402
403
404
405 select {
406 case c.quic.blockedc <- struct{}{}:
407 case <-c.quic.cancelc:
408 return c.sendAlertLocked(alertCloseNotify)
409 }
410
411
412
413 select {
414 case c.quic.signalc <- struct{}{}:
415 c.hand.Write(c.quic.readbuf)
416 c.quic.readbuf = nil
417 case <-c.quic.cancelc:
418 return c.sendAlertLocked(alertCloseNotify)
419 }
420 return nil
421 }
422
View as plain text