1
2
3
4
5 package quic
6
7 import (
8 "context"
9 "crypto/tls"
10 "errors"
11 "fmt"
12 "net"
13 "time"
14 )
15
16
17 func (c *Conn) startTLS(now time.Time, initialConnID []byte, peerHostname string, params transportParameters) error {
18 tlsConfig := c.config.TLSConfig
19 if a, _, err := net.SplitHostPort(peerHostname); err == nil {
20 peerHostname = a
21 }
22 if tlsConfig.ServerName == "" && peerHostname != "" {
23 tlsConfig = tlsConfig.Clone()
24 tlsConfig.ServerName = peerHostname
25 }
26
27 c.keysInitial = initialKeys(initialConnID, c.side)
28
29 qconfig := &tls.QUICConfig{TLSConfig: tlsConfig}
30 if c.side == clientSide {
31 c.tls = tls.QUICClient(qconfig)
32 } else {
33 c.tls = tls.QUICServer(qconfig)
34 }
35 c.tls.SetTransportParameters(marshalTransportParameters(params))
36
37
38
39 if err := c.tls.Start(context.TODO()); err != nil {
40 return err
41 }
42 return c.handleTLSEvents(now)
43 }
44
45 func (c *Conn) handleTLSEvents(now time.Time) error {
46 for {
47 e := c.tls.NextEvent()
48 if c.testHooks != nil {
49 c.testHooks.handleTLSEvent(e)
50 }
51 switch e.Kind {
52 case tls.QUICNoEvent:
53 return nil
54 case tls.QUICSetReadSecret:
55 if err := checkCipherSuite(e.Suite); err != nil {
56 return err
57 }
58 switch e.Level {
59 case tls.QUICEncryptionLevelHandshake:
60 c.keysHandshake.r.init(e.Suite, e.Data)
61 case tls.QUICEncryptionLevelApplication:
62 c.keysAppData.r.init(e.Suite, e.Data)
63 }
64 case tls.QUICSetWriteSecret:
65 if err := checkCipherSuite(e.Suite); err != nil {
66 return err
67 }
68 switch e.Level {
69 case tls.QUICEncryptionLevelHandshake:
70 c.keysHandshake.w.init(e.Suite, e.Data)
71 case tls.QUICEncryptionLevelApplication:
72 c.keysAppData.w.init(e.Suite, e.Data)
73 }
74 case tls.QUICWriteData:
75 var space numberSpace
76 switch e.Level {
77 case tls.QUICEncryptionLevelInitial:
78 space = initialSpace
79 case tls.QUICEncryptionLevelHandshake:
80 space = handshakeSpace
81 case tls.QUICEncryptionLevelApplication:
82 space = appDataSpace
83 default:
84 return fmt.Errorf("quic: internal error: write handshake data at level %v", e.Level)
85 }
86 c.crypto[space].write(e.Data)
87 case tls.QUICHandshakeDone:
88 if c.side == serverSide {
89
90
91
92 c.confirmHandshake(now)
93 }
94 c.handshakeDone()
95 case tls.QUICTransportParameters:
96 params, err := unmarshalTransportParams(e.Data)
97 if err != nil {
98 return err
99 }
100 if err := c.receiveTransportParameters(params); err != nil {
101 return err
102 }
103 }
104 }
105 }
106
107
108 func (c *Conn) handleCrypto(now time.Time, space numberSpace, off int64, data []byte) error {
109 var level tls.QUICEncryptionLevel
110 switch space {
111 case initialSpace:
112 level = tls.QUICEncryptionLevelInitial
113 case handshakeSpace:
114 level = tls.QUICEncryptionLevelHandshake
115 case appDataSpace:
116 level = tls.QUICEncryptionLevelApplication
117 default:
118 return errors.New("quic: internal error: received CRYPTO frame in unexpected number space")
119 }
120 return c.crypto[space].handleCrypto(off, data, func(b []byte) error {
121 return c.tls.HandleData(level, b)
122 })
123 }
124
View as plain text