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  }