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  }