github.com/sagernet/quic-go@v0.43.1-beta.1/internal/qtls/go120.go (about) 1 //go:build go1.20 && !go1.21 2 3 package qtls 4 5 import ( 6 "crypto/tls" 7 "fmt" 8 "unsafe" 9 10 "github.com/quic-go/qtls-go1-20" 11 "github.com/sagernet/quic-go/internal/protocol" 12 ) 13 14 type ( 15 QUICConn = qtls.QUICConn 16 QUICConfig = qtls.QUICConfig 17 QUICEvent = qtls.QUICEvent 18 QUICEventKind = qtls.QUICEventKind 19 QUICEncryptionLevel = qtls.QUICEncryptionLevel 20 AlertError = qtls.AlertError 21 ) 22 23 const ( 24 QUICEncryptionLevelInitial = qtls.QUICEncryptionLevelInitial 25 QUICEncryptionLevelEarly = qtls.QUICEncryptionLevelEarly 26 QUICEncryptionLevelHandshake = qtls.QUICEncryptionLevelHandshake 27 QUICEncryptionLevelApplication = qtls.QUICEncryptionLevelApplication 28 ) 29 30 const ( 31 QUICNoEvent = qtls.QUICNoEvent 32 QUICSetReadSecret = qtls.QUICSetReadSecret 33 QUICSetWriteSecret = qtls.QUICSetWriteSecret 34 QUICWriteData = qtls.QUICWriteData 35 QUICTransportParameters = qtls.QUICTransportParameters 36 QUICTransportParametersRequired = qtls.QUICTransportParametersRequired 37 QUICRejectedEarlyData = qtls.QUICRejectedEarlyData 38 QUICHandshakeDone = qtls.QUICHandshakeDone 39 ) 40 41 func SetupConfigForServer(conf *QUICConfig, enable0RTT bool, getDataForSessionTicket func() []byte, handleSessionTicket func([]byte, bool) bool) { 42 qtls.InitSessionTicketKeys(conf.TLSConfig) 43 conf.TLSConfig = conf.TLSConfig.Clone() 44 conf.TLSConfig.MinVersion = tls.VersionTLS13 45 conf.ExtraConfig = &qtls.ExtraConfig{ 46 Enable0RTT: enable0RTT, 47 Accept0RTT: func(data []byte) bool { 48 return handleSessionTicket(data, true) 49 }, 50 GetAppDataForSessionTicket: getDataForSessionTicket, 51 } 52 } 53 54 func SetupConfigForClient( 55 conf *QUICConfig, 56 getDataForSessionState func(earlyData bool) []byte, 57 setDataFromSessionState func(data []byte, earlyData bool) (allowEarlyData bool), 58 ) { 59 conf.ExtraConfig = &qtls.ExtraConfig{ 60 GetAppDataForSessionState: func() []byte { 61 // qtls only calls the GetAppDataForSessionState when doing 0-RTT 62 return getDataForSessionState(true) 63 }, 64 SetAppDataFromSessionState: func(data []byte) (allowEarlyData bool) { 65 // qtls only calls the SetAppDataFromSessionState for 0-RTT enabled tickets 66 return setDataFromSessionState(data, true) 67 }, 68 } 69 } 70 71 func QUICServer(config *QUICConfig) *QUICConn { 72 return qtls.QUICServer(config) 73 } 74 75 func QUICClient(config *QUICConfig) *QUICConn { 76 return qtls.QUICClient(config) 77 } 78 79 func ToTLSEncryptionLevel(e protocol.EncryptionLevel) qtls.QUICEncryptionLevel { 80 switch e { 81 case protocol.EncryptionInitial: 82 return qtls.QUICEncryptionLevelInitial 83 case protocol.EncryptionHandshake: 84 return qtls.QUICEncryptionLevelHandshake 85 case protocol.Encryption1RTT: 86 return qtls.QUICEncryptionLevelApplication 87 case protocol.Encryption0RTT: 88 return qtls.QUICEncryptionLevelEarly 89 default: 90 panic(fmt.Sprintf("unexpected encryption level: %s", e)) 91 } 92 } 93 94 func FromTLSEncryptionLevel(e qtls.QUICEncryptionLevel) protocol.EncryptionLevel { 95 switch e { 96 case qtls.QUICEncryptionLevelInitial: 97 return protocol.EncryptionInitial 98 case qtls.QUICEncryptionLevelHandshake: 99 return protocol.EncryptionHandshake 100 case qtls.QUICEncryptionLevelApplication: 101 return protocol.Encryption1RTT 102 case qtls.QUICEncryptionLevelEarly: 103 return protocol.Encryption0RTT 104 default: 105 panic(fmt.Sprintf("unexpect encryption level: %s", e)) 106 } 107 } 108 109 //go:linkname cipherSuitesTLS13 github.com/quic-go/qtls-go1-20.cipherSuitesTLS13 110 var cipherSuitesTLS13 []unsafe.Pointer 111 112 //go:linkname defaultCipherSuitesTLS13 github.com/quic-go/qtls-go1-20.defaultCipherSuitesTLS13 113 var defaultCipherSuitesTLS13 []uint16 114 115 //go:linkname defaultCipherSuitesTLS13NoAES github.com/quic-go/qtls-go1-20.defaultCipherSuitesTLS13NoAES 116 var defaultCipherSuitesTLS13NoAES []uint16 117 118 var cipherSuitesModified bool 119 120 // SetCipherSuite modifies the cipherSuiteTLS13 slice of cipher suites inside qtls 121 // such that it only contains the cipher suite with the chosen id. 122 // The reset function returned resets them back to the original value. 123 func SetCipherSuite(id uint16) (reset func()) { 124 if cipherSuitesModified { 125 panic("cipher suites modified multiple times without resetting") 126 } 127 cipherSuitesModified = true 128 129 origCipherSuitesTLS13 := append([]unsafe.Pointer{}, cipherSuitesTLS13...) 130 origDefaultCipherSuitesTLS13 := append([]uint16{}, defaultCipherSuitesTLS13...) 131 origDefaultCipherSuitesTLS13NoAES := append([]uint16{}, defaultCipherSuitesTLS13NoAES...) 132 // The order is given by the order of the slice elements in cipherSuitesTLS13 in qtls. 133 switch id { 134 case tls.TLS_AES_128_GCM_SHA256: 135 cipherSuitesTLS13 = cipherSuitesTLS13[:1] 136 case tls.TLS_CHACHA20_POLY1305_SHA256: 137 cipherSuitesTLS13 = cipherSuitesTLS13[1:2] 138 case tls.TLS_AES_256_GCM_SHA384: 139 cipherSuitesTLS13 = cipherSuitesTLS13[2:] 140 default: 141 panic(fmt.Sprintf("unexpected cipher suite: %d", id)) 142 } 143 defaultCipherSuitesTLS13 = []uint16{id} 144 defaultCipherSuitesTLS13NoAES = []uint16{id} 145 146 return func() { 147 cipherSuitesTLS13 = origCipherSuitesTLS13 148 defaultCipherSuitesTLS13 = origDefaultCipherSuitesTLS13 149 defaultCipherSuitesTLS13NoAES = origDefaultCipherSuitesTLS13NoAES 150 cipherSuitesModified = false 151 } 152 } 153 154 func SendSessionTicket(c *QUICConn, allow0RTT bool) error { 155 return c.SendSessionTicket(allow0RTT) 156 }