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