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
56
57
58 EnableSessionEvents bool
59 }
60
61
62 type QUICEventKind int
63
64 const (
65
66 QUICNoEvent QUICEventKind = iota
67
68
69
70
71
72
73
74 QUICSetReadSecret
75 QUICSetWriteSecret
76
77
78
79 QUICWriteData
80
81
82
83 QUICTransportParameters
84
85
86
87
88
89
90
91
92 QUICTransportParametersRequired
93
94
95
96
97
98 QUICRejectedEarlyData
99
100
101 QUICHandshakeDone
102
103
104
105
106
107
108
109
110
111 QUICResumeSession
112
113
114
115
116
117
118
119 QUICStoreSession
120
121
122
123
124 QUICErrorEvent
125 )
126
127
128
129
130
131 type QUICEvent struct {
132 Kind QUICEventKind
133
134
135 Level QUICEncryptionLevel
136
137
138
139 Data []byte
140
141
142 Suite uint16
143
144
145 SessionState *SessionState
146
147
148
149 Err error
150 }
151
152 type quicState struct {
153 events []QUICEvent
154 nextEvent int
155
156
157
158
159
160 eventArr [8]QUICEvent
161
162 started bool
163 signalc chan struct{}
164 blockedc chan struct{}
165 cancelc <-chan struct{}
166 cancel context.CancelFunc
167
168 waitingForDrain bool
169 errorReturned bool
170
171
172
173
174 readbuf []byte
175
176 transportParams []byte
177
178 enableSessionEvents bool
179 }
180
181
182
183
184
185 func QUICClient(config *QUICConfig) *QUICConn {
186 return newQUICConn(Client(nil, config.TLSConfig), config)
187 }
188
189
190
191
192
193 func QUICServer(config *QUICConfig) *QUICConn {
194 return newQUICConn(Server(nil, config.TLSConfig), config)
195 }
196
197 func newQUICConn(conn *Conn, config *QUICConfig) *QUICConn {
198 conn.quic = &quicState{
199 signalc: make(chan struct{}),
200 blockedc: make(chan struct{}),
201 enableSessionEvents: config.EnableSessionEvents,
202 }
203 conn.quic.events = conn.quic.eventArr[:0]
204 return &QUICConn{
205 conn: conn,
206 }
207 }
208
209
210
211
212
213 func (q *QUICConn) Start(ctx context.Context) error {
214 if q.conn.quic.started {
215 return quicError(errors.New("tls: Start called more than once"))
216 }
217 q.conn.quic.started = true
218 if q.conn.config.MinVersion < VersionTLS13 {
219 return quicError(errors.New("tls: Config MinVersion must be at least TLS 1.3"))
220 }
221 go q.conn.HandshakeContext(ctx)
222 if _, ok := <-q.conn.quic.blockedc; !ok {
223 return q.conn.handshakeErr
224 }
225 return nil
226 }
227
228
229
230 func (q *QUICConn) NextEvent() QUICEvent {
231 qs := q.conn.quic
232 if last := qs.nextEvent - 1; last >= 0 && len(qs.events[last].Data) > 0 {
233
234
235 qs.events[last].Data[0] = 0
236 }
237 if qs.nextEvent >= len(qs.events) && qs.waitingForDrain {
238 qs.waitingForDrain = false
239 <-qs.signalc
240 <-qs.blockedc
241 }
242 if err := q.conn.handshakeErr; err != nil {
243 if qs.errorReturned {
244 return QUICEvent{Kind: QUICNoEvent}
245 }
246 qs.errorReturned = true
247 qs.events = nil
248 qs.nextEvent = 0
249 return QUICEvent{Kind: QUICErrorEvent, Err: q.conn.handshakeErr}
250 }
251 if qs.nextEvent >= len(qs.events) {
252 qs.events = qs.events[:0]
253 qs.nextEvent = 0
254 return QUICEvent{Kind: QUICNoEvent}
255 }
256 e := qs.events[qs.nextEvent]
257 qs.events[qs.nextEvent] = QUICEvent{}
258 qs.nextEvent++
259 return e
260 }
261
262
263 func (q *QUICConn) Close() error {
264 if q.conn.quic.cancel == nil {
265 return nil
266 }
267 q.conn.quic.cancel()
268 for range q.conn.quic.blockedc {
269
270 }
271 return q.conn.handshakeErr
272 }
273
274
275
276 func (q *QUICConn) HandleData(level QUICEncryptionLevel, data []byte) error {
277 c := q.conn
278 if c.in.level != level {
279 return quicError(c.in.setErrorLocked(errors.New("tls: handshake data received at wrong level")))
280 }
281 c.quic.readbuf = data
282 <-c.quic.signalc
283 _, ok := <-c.quic.blockedc
284 if ok {
285
286 return nil
287 }
288
289 c.handshakeMutex.Lock()
290 defer c.handshakeMutex.Unlock()
291 c.hand.Write(c.quic.readbuf)
292 c.quic.readbuf = nil
293 for q.conn.hand.Len() >= 4 && q.conn.handshakeErr == nil {
294 b := q.conn.hand.Bytes()
295 n := int(b[1])<<16 | int(b[2])<<8 | int(b[3])
296 if n > maxHandshake {
297 q.conn.handshakeErr = fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake)
298 break
299 }
300 if len(b) < 4+n {
301 return nil
302 }
303 if err := q.conn.handlePostHandshakeMessage(); err != nil {
304 q.conn.handshakeErr = err
305 }
306 }
307 if q.conn.handshakeErr != nil {
308 return quicError(q.conn.handshakeErr)
309 }
310 return nil
311 }
312
313 type QUICSessionTicketOptions struct {
314
315 EarlyData bool
316 Extra [][]byte
317 }
318
319
320
321
322 func (q *QUICConn) SendSessionTicket(opts QUICSessionTicketOptions) error {
323 c := q.conn
324 if c.config.SessionTicketsDisabled {
325 return nil
326 }
327 if !c.isHandshakeComplete.Load() {
328 return quicError(errors.New("tls: SendSessionTicket called before handshake completed"))
329 }
330 if c.isClient {
331 return quicError(errors.New("tls: SendSessionTicket called on the client"))
332 }
333 if q.sessionTicketSent {
334 return quicError(errors.New("tls: SendSessionTicket called multiple times"))
335 }
336 q.sessionTicketSent = true
337 return quicError(c.sendSessionTicket(opts.EarlyData, opts.Extra))
338 }
339
340
341
342
343
344 func (q *QUICConn) StoreSession(session *SessionState) error {
345 c := q.conn
346 if !c.isClient {
347 return quicError(errors.New("tls: StoreSessionTicket called on the server"))
348 }
349 cacheKey := c.clientSessionCacheKey()
350 if cacheKey == "" {
351 return nil
352 }
353 cs := &ClientSessionState{session: session}
354 c.config.ClientSessionCache.Put(cacheKey, cs)
355 return nil
356 }
357
358
359 func (q *QUICConn) ConnectionState() ConnectionState {
360 return q.conn.ConnectionState()
361 }
362
363
364
365
366
367 func (q *QUICConn) SetTransportParameters(params []byte) {
368 if params == nil {
369 params = []byte{}
370 }
371 q.conn.quic.transportParams = params
372 if q.conn.quic.started {
373 <-q.conn.quic.signalc
374 <-q.conn.quic.blockedc
375 }
376 }
377
378
379
380 func quicError(err error) error {
381 if err == nil {
382 return nil
383 }
384 if _, ok := errors.AsType[AlertError](err); ok {
385 return err
386 }
387 a, ok := errors.AsType[alert](err)
388 if !ok {
389 a = alertInternalError
390 }
391
392
393 return fmt.Errorf("%w%.0w", err, AlertError(a))
394 }
395
396 func (c *Conn) quicReadHandshakeBytes(n int) error {
397 for c.hand.Len() < n {
398 if err := c.quicWaitForSignal(); err != nil {
399 return err
400 }
401 }
402 return nil
403 }
404
405 func (c *Conn) quicSetReadSecret(level QUICEncryptionLevel, suite uint16, secret []byte) error {
406
407
408
409
410 if c.hand.Len() != 0 {
411 c.sendAlert(alertUnexpectedMessage)
412 return errors.New("tls: handshake buffer not empty before setting read traffic secret")
413 }
414 c.quic.events = append(c.quic.events, QUICEvent{
415 Kind: QUICSetReadSecret,
416 Level: level,
417 Suite: suite,
418 Data: secret,
419 })
420 return nil
421 }
422
423 func (c *Conn) quicSetWriteSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
424 c.quic.events = append(c.quic.events, QUICEvent{
425 Kind: QUICSetWriteSecret,
426 Level: level,
427 Suite: suite,
428 Data: secret,
429 })
430 }
431
432 func (c *Conn) quicWriteCryptoData(level QUICEncryptionLevel, data []byte) {
433 var last *QUICEvent
434 if len(c.quic.events) > 0 {
435 last = &c.quic.events[len(c.quic.events)-1]
436 }
437 if last == nil || last.Kind != QUICWriteData || last.Level != level {
438 c.quic.events = append(c.quic.events, QUICEvent{
439 Kind: QUICWriteData,
440 Level: level,
441 })
442 last = &c.quic.events[len(c.quic.events)-1]
443 }
444 last.Data = append(last.Data, data...)
445 }
446
447 func (c *Conn) quicResumeSession(session *SessionState) error {
448 c.quic.events = append(c.quic.events, QUICEvent{
449 Kind: QUICResumeSession,
450 SessionState: session,
451 })
452 c.quic.waitingForDrain = true
453 for c.quic.waitingForDrain {
454 if err := c.quicWaitForSignal(); err != nil {
455 return err
456 }
457 }
458 return nil
459 }
460
461 func (c *Conn) quicStoreSession(session *SessionState) {
462 c.quic.events = append(c.quic.events, QUICEvent{
463 Kind: QUICStoreSession,
464 SessionState: session,
465 })
466 }
467
468 func (c *Conn) quicSetTransportParameters(params []byte) {
469 c.quic.events = append(c.quic.events, QUICEvent{
470 Kind: QUICTransportParameters,
471 Data: params,
472 })
473 }
474
475 func (c *Conn) quicGetTransportParameters() ([]byte, error) {
476 if c.quic.transportParams == nil {
477 c.quic.events = append(c.quic.events, QUICEvent{
478 Kind: QUICTransportParametersRequired,
479 })
480 }
481 for c.quic.transportParams == nil {
482 if err := c.quicWaitForSignal(); err != nil {
483 return nil, err
484 }
485 }
486 return c.quic.transportParams, nil
487 }
488
489 func (c *Conn) quicHandshakeComplete() {
490 c.quic.events = append(c.quic.events, QUICEvent{
491 Kind: QUICHandshakeDone,
492 })
493 }
494
495 func (c *Conn) quicRejectedEarlyData() {
496 c.quic.events = append(c.quic.events, QUICEvent{
497 Kind: QUICRejectedEarlyData,
498 })
499 }
500
501
502
503
504
505
506 func (c *Conn) quicWaitForSignal() error {
507
508
509 c.handshakeMutex.Unlock()
510 defer c.handshakeMutex.Lock()
511
512
513
514 select {
515 case c.quic.blockedc <- struct{}{}:
516 case <-c.quic.cancelc:
517 return c.sendAlertLocked(alertCloseNotify)
518 }
519
520
521
522 select {
523 case c.quic.signalc <- struct{}{}:
524 c.hand.Write(c.quic.readbuf)
525 c.quic.readbuf = nil
526 case <-c.quic.cancelc:
527 return c.sendAlertLocked(alertCloseNotify)
528 }
529 return nil
530 }
531
View as plain text