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) {
406 c.quic.events = append(c.quic.events, QUICEvent{
407 Kind: QUICSetReadSecret,
408 Level: level,
409 Suite: suite,
410 Data: secret,
411 })
412 }
413
414 func (c *Conn) quicSetWriteSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
415 c.quic.events = append(c.quic.events, QUICEvent{
416 Kind: QUICSetWriteSecret,
417 Level: level,
418 Suite: suite,
419 Data: secret,
420 })
421 }
422
423 func (c *Conn) quicWriteCryptoData(level QUICEncryptionLevel, data []byte) {
424 var last *QUICEvent
425 if len(c.quic.events) > 0 {
426 last = &c.quic.events[len(c.quic.events)-1]
427 }
428 if last == nil || last.Kind != QUICWriteData || last.Level != level {
429 c.quic.events = append(c.quic.events, QUICEvent{
430 Kind: QUICWriteData,
431 Level: level,
432 })
433 last = &c.quic.events[len(c.quic.events)-1]
434 }
435 last.Data = append(last.Data, data...)
436 }
437
438 func (c *Conn) quicResumeSession(session *SessionState) error {
439 c.quic.events = append(c.quic.events, QUICEvent{
440 Kind: QUICResumeSession,
441 SessionState: session,
442 })
443 c.quic.waitingForDrain = true
444 for c.quic.waitingForDrain {
445 if err := c.quicWaitForSignal(); err != nil {
446 return err
447 }
448 }
449 return nil
450 }
451
452 func (c *Conn) quicStoreSession(session *SessionState) {
453 c.quic.events = append(c.quic.events, QUICEvent{
454 Kind: QUICStoreSession,
455 SessionState: session,
456 })
457 }
458
459 func (c *Conn) quicSetTransportParameters(params []byte) {
460 c.quic.events = append(c.quic.events, QUICEvent{
461 Kind: QUICTransportParameters,
462 Data: params,
463 })
464 }
465
466 func (c *Conn) quicGetTransportParameters() ([]byte, error) {
467 if c.quic.transportParams == nil {
468 c.quic.events = append(c.quic.events, QUICEvent{
469 Kind: QUICTransportParametersRequired,
470 })
471 }
472 for c.quic.transportParams == nil {
473 if err := c.quicWaitForSignal(); err != nil {
474 return nil, err
475 }
476 }
477 return c.quic.transportParams, nil
478 }
479
480 func (c *Conn) quicHandshakeComplete() {
481 c.quic.events = append(c.quic.events, QUICEvent{
482 Kind: QUICHandshakeDone,
483 })
484 }
485
486 func (c *Conn) quicRejectedEarlyData() {
487 c.quic.events = append(c.quic.events, QUICEvent{
488 Kind: QUICRejectedEarlyData,
489 })
490 }
491
492
493
494
495
496
497 func (c *Conn) quicWaitForSignal() error {
498
499
500 c.handshakeMutex.Unlock()
501 defer c.handshakeMutex.Lock()
502
503
504
505 select {
506 case c.quic.blockedc <- struct{}{}:
507 case <-c.quic.cancelc:
508 return c.sendAlertLocked(alertCloseNotify)
509 }
510
511
512
513 select {
514 case c.quic.signalc <- struct{}{}:
515 c.hand.Write(c.quic.readbuf)
516 c.quic.readbuf = nil
517 case <-c.quic.cancelc:
518 return c.sendAlertLocked(alertCloseNotify)
519 }
520 return nil
521 }
522
View as plain text