mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-28 13:49:58 +00:00
TUN-8006: Update quic-go to latest upstream
This commit is contained in:
13
vendor/github.com/quic-go/qtls-go1-20/alert.go
generated
vendored
13
vendor/github.com/quic-go/qtls-go1-20/alert.go
generated
vendored
@@ -6,10 +6,17 @@ package qtls
|
||||
|
||||
import "strconv"
|
||||
|
||||
type alert uint8
|
||||
// An AlertError is a TLS alert.
|
||||
//
|
||||
// When using a QUIC transport, QUICConn methods will return an error
|
||||
// which wraps AlertError rather than sending a TLS alert.
|
||||
type AlertError uint8
|
||||
|
||||
// Alert is a TLS alert
|
||||
type Alert = alert
|
||||
func (e AlertError) Error() string {
|
||||
return alert(e).String()
|
||||
}
|
||||
|
||||
type alert uint8
|
||||
|
||||
const (
|
||||
// alert level
|
||||
|
30
vendor/github.com/quic-go/qtls-go1-20/cipher_suites.go
generated
vendored
30
vendor/github.com/quic-go/qtls-go1-20/cipher_suites.go
generated
vendored
@@ -15,8 +15,10 @@ import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"hash"
|
||||
"runtime"
|
||||
|
||||
"golang.org/x/crypto/chacha20poly1305"
|
||||
"golang.org/x/sys/cpu"
|
||||
)
|
||||
|
||||
// CipherSuite is a TLS cipher suite. Note that most functions in this package
|
||||
@@ -195,17 +197,6 @@ type cipherSuiteTLS13 struct {
|
||||
hash crypto.Hash
|
||||
}
|
||||
|
||||
type CipherSuiteTLS13 struct {
|
||||
ID uint16
|
||||
KeyLen int
|
||||
Hash crypto.Hash
|
||||
AEAD func(key, fixedNonce []byte) cipher.AEAD
|
||||
}
|
||||
|
||||
func (c *CipherSuiteTLS13) IVLen() int {
|
||||
return aeadNonceLength
|
||||
}
|
||||
|
||||
var cipherSuitesTLS13 = []*cipherSuiteTLS13{ // TODO: replace with a map.
|
||||
{TLS_AES_128_GCM_SHA256, 16, aeadAESGCMTLS13, crypto.SHA256},
|
||||
{TLS_CHACHA20_POLY1305_SHA256, 32, aeadChaCha20Poly1305, crypto.SHA256},
|
||||
@@ -362,6 +353,18 @@ var defaultCipherSuitesTLS13NoAES = []uint16{
|
||||
TLS_AES_256_GCM_SHA384,
|
||||
}
|
||||
|
||||
var (
|
||||
hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ
|
||||
hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL
|
||||
// Keep in sync with crypto/aes/cipher_s390x.go.
|
||||
hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR &&
|
||||
(cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM)
|
||||
|
||||
hasAESGCMHardwareSupport = runtime.GOARCH == "amd64" && hasGCMAsmAMD64 ||
|
||||
runtime.GOARCH == "arm64" && hasGCMAsmARM64 ||
|
||||
runtime.GOARCH == "s390x" && hasGCMAsmS390X
|
||||
)
|
||||
|
||||
var aesgcmCiphers = map[uint16]bool{
|
||||
// TLS 1.2
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: true,
|
||||
@@ -519,11 +522,6 @@ func aeadAESGCM(key, noncePrefix []byte) aead {
|
||||
return ret
|
||||
}
|
||||
|
||||
// AEADAESGCMTLS13 creates a new AES-GCM AEAD for TLS 1.3
|
||||
func AEADAESGCMTLS13(key, fixedNonce []byte) cipher.AEAD {
|
||||
return aeadAESGCMTLS13(key, fixedNonce)
|
||||
}
|
||||
|
||||
func aeadAESGCMTLS13(key, nonceMask []byte) aead {
|
||||
if len(nonceMask) != aeadNonceLength {
|
||||
panic("tls: internal error: wrong nonce length")
|
||||
|
106
vendor/github.com/quic-go/qtls-go1-20/common.go
generated
vendored
106
vendor/github.com/quic-go/qtls-go1-20/common.go
generated
vendored
@@ -82,11 +82,6 @@ const (
|
||||
compressionNone uint8 = 0
|
||||
)
|
||||
|
||||
type Extension struct {
|
||||
Type uint16
|
||||
Data []byte
|
||||
}
|
||||
|
||||
// TLS extension numbers
|
||||
const (
|
||||
extensionServerName uint16 = 0
|
||||
@@ -105,6 +100,7 @@ const (
|
||||
extensionCertificateAuthorities uint16 = 47
|
||||
extensionSignatureAlgorithmsCert uint16 = 50
|
||||
extensionKeyShare uint16 = 51
|
||||
extensionQUICTransportParameters uint16 = 57
|
||||
extensionRenegotiationInfo uint16 = 0xff01
|
||||
)
|
||||
|
||||
@@ -113,14 +109,6 @@ const (
|
||||
scsvRenegotiation uint16 = 0x00ff
|
||||
)
|
||||
|
||||
type EncryptionLevel uint8
|
||||
|
||||
const (
|
||||
EncryptionHandshake EncryptionLevel = iota
|
||||
Encryption0RTT
|
||||
EncryptionApplication
|
||||
)
|
||||
|
||||
// CurveID is a tls.CurveID
|
||||
type CurveID = tls.CurveID
|
||||
|
||||
@@ -294,12 +282,6 @@ type connectionState struct {
|
||||
ekm func(label string, context []byte, length int) ([]byte, error)
|
||||
}
|
||||
|
||||
type ConnectionStateWith0RTT struct {
|
||||
ConnectionState
|
||||
|
||||
Used0RTT bool // true if 0-RTT was both offered and accepted
|
||||
}
|
||||
|
||||
// ClientAuthType is tls.ClientAuthType
|
||||
type ClientAuthType = tls.ClientAuthType
|
||||
|
||||
@@ -349,8 +331,6 @@ type clientSessionState struct {
|
||||
// goroutines. Up to TLS 1.2, only ticket-based resumption is supported, not
|
||||
// SessionID-based resumption. In TLS 1.3 they were merged into PSK modes, which
|
||||
// are supported via this interface.
|
||||
//
|
||||
//go:generate sh -c "mockgen -package qtls -destination mock_client_session_cache_test.go github.com/quic-go/qtls-go1-20 ClientSessionCache"
|
||||
type ClientSessionCache = tls.ClientSessionCache
|
||||
|
||||
// SignatureScheme is a tls.SignatureScheme
|
||||
@@ -736,64 +716,22 @@ type config struct {
|
||||
autoSessionTicketKeys []ticketKey
|
||||
}
|
||||
|
||||
// A RecordLayer handles encrypting and decrypting of TLS messages.
|
||||
type RecordLayer interface {
|
||||
SetReadKey(encLevel EncryptionLevel, suite *CipherSuiteTLS13, trafficSecret []byte)
|
||||
SetWriteKey(encLevel EncryptionLevel, suite *CipherSuiteTLS13, trafficSecret []byte)
|
||||
ReadHandshakeMessage() ([]byte, error)
|
||||
WriteRecord([]byte) (int, error)
|
||||
SendAlert(uint8)
|
||||
}
|
||||
|
||||
type ExtraConfig struct {
|
||||
// GetExtensions, if not nil, is called before a message that allows
|
||||
// sending of extensions is sent.
|
||||
// Currently only implemented for the ClientHello message (for the client)
|
||||
// and for the EncryptedExtensions message (for the server).
|
||||
// Only valid for TLS 1.3.
|
||||
GetExtensions func(handshakeMessageType uint8) []Extension
|
||||
|
||||
// ReceivedExtensions, if not nil, is called when a message that allows the
|
||||
// inclusion of extensions is received.
|
||||
// It is called with an empty slice of extensions, if the message didn't
|
||||
// contain any extensions.
|
||||
// Currently only implemented for the ClientHello message (sent by the
|
||||
// client) and for the EncryptedExtensions message (sent by the server).
|
||||
// Only valid for TLS 1.3.
|
||||
ReceivedExtensions func(handshakeMessageType uint8, exts []Extension)
|
||||
|
||||
// AlternativeRecordLayer is used by QUIC
|
||||
AlternativeRecordLayer RecordLayer
|
||||
|
||||
// Enforce the selection of a supported application protocol.
|
||||
// Only works for TLS 1.3.
|
||||
// If enabled, client and server have to agree on an application protocol.
|
||||
// Otherwise, connection establishment fails.
|
||||
EnforceNextProtoSelection bool
|
||||
|
||||
// If MaxEarlyData is greater than 0, the client will be allowed to send early
|
||||
// data when resuming a session.
|
||||
// Requires the AlternativeRecordLayer to be set.
|
||||
// If Enable0RTT is enabled, the client will be allowed to send early data when resuming a session.
|
||||
//
|
||||
// It has no meaning on the client.
|
||||
MaxEarlyData uint32
|
||||
Enable0RTT bool
|
||||
|
||||
// GetAppDataForSessionTicket requests application data to be sent with a session ticket.
|
||||
//
|
||||
// It has no meaning on the client.
|
||||
GetAppDataForSessionTicket func() []byte
|
||||
|
||||
// The Accept0RTT callback is called when the client offers 0-RTT.
|
||||
// The server then has to decide if it wants to accept or reject 0-RTT.
|
||||
// It is only used for servers.
|
||||
Accept0RTT func(appData []byte) bool
|
||||
|
||||
// 0RTTRejected is called when the server rejectes 0-RTT.
|
||||
// It is only used for clients.
|
||||
Rejected0RTT func()
|
||||
|
||||
// If set, the client will export the 0-RTT key when resuming a session that
|
||||
// allows sending of early data.
|
||||
// Requires the AlternativeRecordLayer to be set.
|
||||
//
|
||||
// It has no meaning to the server.
|
||||
Enable0RTT bool
|
||||
|
||||
// Is called when the client saves a session ticket to the session ticket.
|
||||
// This gives the application the opportunity to save some data along with the ticket,
|
||||
// which can be restored when the session ticket is used.
|
||||
@@ -801,29 +739,20 @@ type ExtraConfig struct {
|
||||
|
||||
// Is called when the client uses a session ticket.
|
||||
// Restores the application data that was saved earlier on GetAppDataForSessionTicket.
|
||||
SetAppDataFromSessionState func([]byte)
|
||||
SetAppDataFromSessionState func([]byte) (allowEarlyData bool)
|
||||
}
|
||||
|
||||
// Clone clones.
|
||||
func (c *ExtraConfig) Clone() *ExtraConfig {
|
||||
return &ExtraConfig{
|
||||
GetExtensions: c.GetExtensions,
|
||||
ReceivedExtensions: c.ReceivedExtensions,
|
||||
AlternativeRecordLayer: c.AlternativeRecordLayer,
|
||||
EnforceNextProtoSelection: c.EnforceNextProtoSelection,
|
||||
MaxEarlyData: c.MaxEarlyData,
|
||||
Enable0RTT: c.Enable0RTT,
|
||||
GetAppDataForSessionTicket: c.GetAppDataForSessionTicket,
|
||||
Accept0RTT: c.Accept0RTT,
|
||||
Rejected0RTT: c.Rejected0RTT,
|
||||
GetAppDataForSessionState: c.GetAppDataForSessionState,
|
||||
SetAppDataFromSessionState: c.SetAppDataFromSessionState,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ExtraConfig) usesAlternativeRecordLayer() bool {
|
||||
return c != nil && c.AlternativeRecordLayer != nil
|
||||
}
|
||||
|
||||
const (
|
||||
// ticketKeyNameLen is the number of bytes of identifier that is prepended to
|
||||
// an encrypted session ticket in order to identify the key used to encrypt it.
|
||||
@@ -1384,7 +1313,6 @@ func (c *config) BuildNameToCertificate() {
|
||||
|
||||
const (
|
||||
keyLogLabelTLS12 = "CLIENT_RANDOM"
|
||||
keyLogLabelEarlyTraffic = "CLIENT_EARLY_TRAFFIC_SECRET"
|
||||
keyLogLabelClientHandshake = "CLIENT_HANDSHAKE_TRAFFIC_SECRET"
|
||||
keyLogLabelServerHandshake = "SERVER_HANDSHAKE_TRAFFIC_SECRET"
|
||||
keyLogLabelClientTraffic = "CLIENT_TRAFFIC_SECRET_0"
|
||||
@@ -1523,16 +1451,4 @@ func isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlg
|
||||
}
|
||||
|
||||
// CertificateVerificationError is returned when certificate verification fails during the handshake.
|
||||
type CertificateVerificationError struct {
|
||||
// UnverifiedCertificates and its contents should not be modified.
|
||||
UnverifiedCertificates []*x509.Certificate
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *CertificateVerificationError) Error() string {
|
||||
return fmt.Sprintf("tls: failed to verify certificate: %s", e.Err)
|
||||
}
|
||||
|
||||
func (e *CertificateVerificationError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
type CertificateVerificationError = tls.CertificateVerificationError
|
||||
|
225
vendor/github.com/quic-go/qtls-go1-20/conn.go
generated
vendored
225
vendor/github.com/quic-go/qtls-go1-20/conn.go
generated
vendored
@@ -29,6 +29,7 @@ type Conn struct {
|
||||
conn net.Conn
|
||||
isClient bool
|
||||
handshakeFn func(context.Context) error // (*Conn).clientHandshake or serverHandshake
|
||||
quic *quicState // nil for non-QUIC connections
|
||||
|
||||
// isHandshakeComplete is true if the connection is currently transferring
|
||||
// application data (i.e. is not currently processing a handshake).
|
||||
@@ -40,11 +41,10 @@ type Conn struct {
|
||||
vers uint16 // TLS version
|
||||
haveVers bool // version has been negotiated
|
||||
config *config // configuration passed to constructor
|
||||
extraConfig *ExtraConfig
|
||||
// handshakes counts the number of handshakes performed on the
|
||||
// connection so far. If renegotiation is disabled then this is either
|
||||
// zero or one.
|
||||
extraConfig *ExtraConfig
|
||||
|
||||
handshakes int
|
||||
didResume bool // whether this connection was a session resumption
|
||||
cipherSuite uint16
|
||||
@@ -65,13 +65,8 @@ type Conn struct {
|
||||
secureRenegotiation bool
|
||||
// ekm is a closure for exporting keying material.
|
||||
ekm func(label string, context []byte, length int) ([]byte, error)
|
||||
// For the client:
|
||||
// resumptionSecret is the resumption_master_secret for handling
|
||||
// NewSessionTicket messages. nil if config.SessionTicketsDisabled.
|
||||
// For the server:
|
||||
// resumptionSecret is the resumption_master_secret for generating
|
||||
// NewSessionTicket messages. Only used when the alternative record
|
||||
// layer is set. nil if config.SessionTicketsDisabled.
|
||||
// or sending NewSessionTicket messages.
|
||||
resumptionSecret []byte
|
||||
|
||||
// ticketKeys is the set of active session ticket keys for this
|
||||
@@ -123,12 +118,7 @@ type Conn struct {
|
||||
// the rest of the bits are the number of goroutines in Conn.Write.
|
||||
activeCall atomic.Int32
|
||||
|
||||
used0RTT bool
|
||||
|
||||
tmp [16]byte
|
||||
|
||||
connStateMutex sync.Mutex
|
||||
connState ConnectionStateWith0RTT
|
||||
}
|
||||
|
||||
// Access to net.Conn methods.
|
||||
@@ -188,9 +178,8 @@ type halfConn struct {
|
||||
nextCipher any // next encryption state
|
||||
nextMac hash.Hash // next MAC algorithm
|
||||
|
||||
trafficSecret []byte // current TLS 1.3 traffic secret
|
||||
|
||||
setKeyCallback func(encLevel EncryptionLevel, suite *CipherSuiteTLS13, trafficSecret []byte)
|
||||
level QUICEncryptionLevel // current QUIC encryption level
|
||||
trafficSecret []byte // current TLS 1.3 traffic secret
|
||||
}
|
||||
|
||||
type permanentError struct {
|
||||
@@ -235,20 +224,9 @@ func (hc *halfConn) changeCipherSpec() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hc *halfConn) exportKey(encLevel EncryptionLevel, suite *cipherSuiteTLS13, trafficSecret []byte) {
|
||||
if hc.setKeyCallback != nil {
|
||||
s := &CipherSuiteTLS13{
|
||||
ID: suite.id,
|
||||
KeyLen: suite.keyLen,
|
||||
Hash: suite.hash,
|
||||
AEAD: func(key, fixedNonce []byte) cipher.AEAD { return suite.aead(key, fixedNonce) },
|
||||
}
|
||||
hc.setKeyCallback(encLevel, s, trafficSecret)
|
||||
}
|
||||
}
|
||||
|
||||
func (hc *halfConn) setTrafficSecret(suite *cipherSuiteTLS13, secret []byte) {
|
||||
func (hc *halfConn) setTrafficSecret(suite *cipherSuiteTLS13, level QUICEncryptionLevel, secret []byte) {
|
||||
hc.trafficSecret = secret
|
||||
hc.level = level
|
||||
key, iv := suite.trafficKey(secret)
|
||||
hc.cipher = suite.aead(key, iv)
|
||||
for i := range hc.seq {
|
||||
@@ -481,13 +459,6 @@ func (hc *halfConn) decrypt(record []byte) ([]byte, recordType, error) {
|
||||
return plaintext, typ, nil
|
||||
}
|
||||
|
||||
func (c *Conn) setAlternativeRecordLayer() {
|
||||
if c.extraConfig != nil && c.extraConfig.AlternativeRecordLayer != nil {
|
||||
c.in.setKeyCallback = c.extraConfig.AlternativeRecordLayer.SetReadKey
|
||||
c.out.setKeyCallback = c.extraConfig.AlternativeRecordLayer.SetWriteKey
|
||||
}
|
||||
}
|
||||
|
||||
// sliceForAppend extends the input slice by n bytes. head is the full extended
|
||||
// slice, while tail is the appended part. If the original slice has sufficient
|
||||
// capacity no allocation is performed.
|
||||
@@ -646,6 +617,10 @@ func (c *Conn) readRecordOrCCS(expectChangeCipherSpec bool) error {
|
||||
}
|
||||
c.input.Reset(nil)
|
||||
|
||||
if c.quic != nil {
|
||||
return c.in.setErrorLocked(errors.New("tls: internal error: attempted to read record with QUIC transport"))
|
||||
}
|
||||
|
||||
// Read header, payload.
|
||||
if err := c.readFromUntil(c.conn, recordHeaderLen); err != nil {
|
||||
// RFC 8446, Section 6.1 suggests that EOF without an alertCloseNotify
|
||||
@@ -729,6 +704,9 @@ func (c *Conn) readRecordOrCCS(expectChangeCipherSpec bool) error {
|
||||
return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
|
||||
|
||||
case recordTypeAlert:
|
||||
if c.quic != nil {
|
||||
return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
|
||||
}
|
||||
if len(data) != 2 {
|
||||
return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
|
||||
}
|
||||
@@ -846,6 +824,9 @@ func (c *Conn) readFromUntil(r io.Reader, n int) error {
|
||||
|
||||
// sendAlert sends a TLS alert message.
|
||||
func (c *Conn) sendAlertLocked(err alert) error {
|
||||
if c.quic != nil {
|
||||
return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
|
||||
}
|
||||
switch err {
|
||||
case alertNoRenegotiation, alertCloseNotify:
|
||||
c.tmp[0] = alertLevelWarning
|
||||
@@ -865,11 +846,6 @@ func (c *Conn) sendAlertLocked(err alert) error {
|
||||
|
||||
// sendAlert sends a TLS alert message.
|
||||
func (c *Conn) sendAlert(err alert) error {
|
||||
if c.extraConfig != nil && c.extraConfig.AlternativeRecordLayer != nil {
|
||||
c.extraConfig.AlternativeRecordLayer.SendAlert(uint8(err))
|
||||
return &net.OpError{Op: "local error", Err: err}
|
||||
}
|
||||
|
||||
c.out.Lock()
|
||||
defer c.out.Unlock()
|
||||
return c.sendAlertLocked(err)
|
||||
@@ -985,6 +961,19 @@ var outBufPool = sync.Pool{
|
||||
// writeRecordLocked writes a TLS record with the given type and payload to the
|
||||
// connection and updates the record layer state.
|
||||
func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) {
|
||||
if c.quic != nil {
|
||||
if typ != recordTypeHandshake {
|
||||
return 0, errors.New("tls: internal error: sending non-handshake message to QUIC transport")
|
||||
}
|
||||
c.quicWriteCryptoData(c.out.level, data)
|
||||
if !c.buffering {
|
||||
if _, err := c.flush(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return len(data), nil
|
||||
}
|
||||
|
||||
outBufPtr := outBufPool.Get().(*[]byte)
|
||||
outBuf := *outBufPtr
|
||||
defer func() {
|
||||
@@ -1046,69 +1035,63 @@ func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) {
|
||||
// the record layer state. If transcript is non-nil the marshalled message is
|
||||
// written to it.
|
||||
func (c *Conn) writeHandshakeRecord(msg handshakeMessage, transcript transcriptHash) (int, error) {
|
||||
c.out.Lock()
|
||||
defer c.out.Unlock()
|
||||
|
||||
data, err := msg.marshal()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
c.out.Lock()
|
||||
defer c.out.Unlock()
|
||||
|
||||
if transcript != nil {
|
||||
transcript.Write(data)
|
||||
}
|
||||
|
||||
if c.extraConfig != nil && c.extraConfig.AlternativeRecordLayer != nil {
|
||||
return c.extraConfig.AlternativeRecordLayer.WriteRecord(data)
|
||||
}
|
||||
|
||||
return c.writeRecordLocked(recordTypeHandshake, data)
|
||||
}
|
||||
|
||||
// writeChangeCipherRecord writes a ChangeCipherSpec message to the connection and
|
||||
// updates the record layer state.
|
||||
func (c *Conn) writeChangeCipherRecord() error {
|
||||
if c.extraConfig != nil && c.extraConfig.AlternativeRecordLayer != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
c.out.Lock()
|
||||
defer c.out.Unlock()
|
||||
_, err := c.writeRecordLocked(recordTypeChangeCipherSpec, []byte{1})
|
||||
return err
|
||||
}
|
||||
|
||||
// readHandshakeBytes reads handshake data until c.hand contains at least n bytes.
|
||||
func (c *Conn) readHandshakeBytes(n int) error {
|
||||
if c.quic != nil {
|
||||
return c.quicReadHandshakeBytes(n)
|
||||
}
|
||||
for c.hand.Len() < n {
|
||||
if err := c.readRecord(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// readHandshake reads the next handshake message from
|
||||
// the record layer. If transcript is non-nil, the message
|
||||
// is written to the passed transcriptHash.
|
||||
func (c *Conn) readHandshake(transcript transcriptHash) (any, error) {
|
||||
var data []byte
|
||||
if c.extraConfig != nil && c.extraConfig.AlternativeRecordLayer != nil {
|
||||
var err error
|
||||
data, err = c.extraConfig.AlternativeRecordLayer.ReadHandshakeMessage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
for c.hand.Len() < 4 {
|
||||
if err := c.readRecord(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
data = c.hand.Bytes()
|
||||
n := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
|
||||
if n > maxHandshake {
|
||||
c.sendAlertLocked(alertInternalError)
|
||||
return nil, c.in.setErrorLocked(fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake))
|
||||
}
|
||||
for c.hand.Len() < 4+n {
|
||||
if err := c.readRecord(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
data = c.hand.Next(4 + n)
|
||||
if err := c.readHandshakeBytes(4); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data := c.hand.Bytes()
|
||||
n := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
|
||||
if n > maxHandshake {
|
||||
c.sendAlertLocked(alertInternalError)
|
||||
return nil, c.in.setErrorLocked(fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake))
|
||||
}
|
||||
if err := c.readHandshakeBytes(4 + n); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = c.hand.Next(4 + n)
|
||||
return c.unmarshalHandshakeMessage(data, transcript)
|
||||
}
|
||||
|
||||
func (c *Conn) unmarshalHandshakeMessage(data []byte, transcript transcriptHash) (handshakeMessage, error) {
|
||||
var m handshakeMessage
|
||||
switch data[0] {
|
||||
case typeHelloRequest:
|
||||
@@ -1288,10 +1271,6 @@ func (c *Conn) handleRenegotiation() error {
|
||||
return c.handshakeErr
|
||||
}
|
||||
|
||||
func (c *Conn) HandlePostHandshakeMessage() error {
|
||||
return c.handlePostHandshakeMessage()
|
||||
}
|
||||
|
||||
// handlePostHandshakeMessage processes a handshake message arrived after the
|
||||
// handshake is complete. Up to TLS 1.2, it indicates the start of a renegotiation.
|
||||
func (c *Conn) handlePostHandshakeMessage() error {
|
||||
@@ -1303,7 +1282,6 @@ func (c *Conn) handlePostHandshakeMessage() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.retryCount++
|
||||
if c.retryCount > maxUselessRecords {
|
||||
c.sendAlert(alertUnexpectedMessage)
|
||||
@@ -1315,20 +1293,28 @@ func (c *Conn) handlePostHandshakeMessage() error {
|
||||
return c.handleNewSessionTicket(msg)
|
||||
case *keyUpdateMsg:
|
||||
return c.handleKeyUpdate(msg)
|
||||
default:
|
||||
c.sendAlert(alertUnexpectedMessage)
|
||||
return fmt.Errorf("tls: received unexpected handshake message of type %T", msg)
|
||||
}
|
||||
// The QUIC layer is supposed to treat an unexpected post-handshake CertificateRequest
|
||||
// as a QUIC-level PROTOCOL_VIOLATION error (RFC 9001, Section 4.4). Returning an
|
||||
// unexpected_message alert here doesn't provide it with enough information to distinguish
|
||||
// this condition from other unexpected messages. This is probably fine.
|
||||
c.sendAlert(alertUnexpectedMessage)
|
||||
return fmt.Errorf("tls: received unexpected handshake message of type %T", msg)
|
||||
}
|
||||
|
||||
func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
|
||||
if c.quic != nil {
|
||||
c.sendAlert(alertUnexpectedMessage)
|
||||
return c.in.setErrorLocked(errors.New("tls: received unexpected key update message"))
|
||||
}
|
||||
|
||||
cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite)
|
||||
if cipherSuite == nil {
|
||||
return c.in.setErrorLocked(c.sendAlert(alertInternalError))
|
||||
}
|
||||
|
||||
newSecret := cipherSuite.nextTrafficSecret(c.in.trafficSecret)
|
||||
c.in.setTrafficSecret(cipherSuite, newSecret)
|
||||
c.in.setTrafficSecret(cipherSuite, QUICEncryptionLevelInitial, newSecret)
|
||||
|
||||
if keyUpdate.updateRequested {
|
||||
c.out.Lock()
|
||||
@@ -1347,7 +1333,7 @@ func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
|
||||
}
|
||||
|
||||
newSecret := cipherSuite.nextTrafficSecret(c.out.trafficSecret)
|
||||
c.out.setTrafficSecret(cipherSuite, newSecret)
|
||||
c.out.setTrafficSecret(cipherSuite, QUICEncryptionLevelInitial, newSecret)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -1508,12 +1494,15 @@ func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
|
||||
// this cancellation. In the former case, we need to close the connection.
|
||||
defer cancel()
|
||||
|
||||
// Start the "interrupter" goroutine, if this context might be canceled.
|
||||
// (The background context cannot).
|
||||
//
|
||||
// The interrupter goroutine waits for the input context to be done and
|
||||
// closes the connection if this happens before the function returns.
|
||||
if ctx.Done() != nil {
|
||||
if c.quic != nil {
|
||||
c.quic.cancelc = handshakeCtx.Done()
|
||||
c.quic.cancel = cancel
|
||||
} else if ctx.Done() != nil {
|
||||
// Start the "interrupter" goroutine, if this context might be canceled.
|
||||
// (The background context cannot).
|
||||
//
|
||||
// The interrupter goroutine waits for the input context to be done and
|
||||
// closes the connection if this happens before the function returns.
|
||||
done := make(chan struct{})
|
||||
interruptRes := make(chan error, 1)
|
||||
defer func() {
|
||||
@@ -1564,21 +1553,38 @@ func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
|
||||
panic("tls: internal error: handshake returned an error but is marked successful")
|
||||
}
|
||||
|
||||
if c.quic != nil {
|
||||
if c.handshakeErr == nil {
|
||||
c.quicHandshakeComplete()
|
||||
// Provide the 1-RTT read secret now that the handshake is complete.
|
||||
// The QUIC layer MUST NOT decrypt 1-RTT packets prior to completing
|
||||
// the handshake (RFC 9001, Section 5.7).
|
||||
c.quicSetReadSecret(QUICEncryptionLevelApplication, c.cipherSuite, c.in.trafficSecret)
|
||||
} else {
|
||||
var a alert
|
||||
c.out.Lock()
|
||||
if !errors.As(c.out.err, &a) {
|
||||
a = alertInternalError
|
||||
}
|
||||
c.out.Unlock()
|
||||
// Return an error which wraps both the handshake error and
|
||||
// any alert error we may have sent, or alertInternalError
|
||||
// if we didn't send an alert.
|
||||
// Truncate the text of the alert to 0 characters.
|
||||
c.handshakeErr = fmt.Errorf("%w%.0w", c.handshakeErr, AlertError(a))
|
||||
}
|
||||
close(c.quic.blockedc)
|
||||
close(c.quic.signalc)
|
||||
}
|
||||
|
||||
return c.handshakeErr
|
||||
}
|
||||
|
||||
// ConnectionState returns basic TLS details about the connection.
|
||||
func (c *Conn) ConnectionState() ConnectionState {
|
||||
c.connStateMutex.Lock()
|
||||
defer c.connStateMutex.Unlock()
|
||||
return c.connState.ConnectionState
|
||||
}
|
||||
|
||||
// ConnectionStateWith0RTT returns basic TLS details (incl. 0-RTT status) about the connection.
|
||||
func (c *Conn) ConnectionStateWith0RTT() ConnectionStateWith0RTT {
|
||||
c.connStateMutex.Lock()
|
||||
defer c.connStateMutex.Unlock()
|
||||
return c.connState
|
||||
c.handshakeMutex.Lock()
|
||||
defer c.handshakeMutex.Unlock()
|
||||
return c.connectionStateLocked()
|
||||
}
|
||||
|
||||
func (c *Conn) connectionStateLocked() ConnectionState {
|
||||
@@ -1609,15 +1615,6 @@ func (c *Conn) connectionStateLocked() ConnectionState {
|
||||
return toConnectionState(state)
|
||||
}
|
||||
|
||||
func (c *Conn) updateConnectionState() {
|
||||
c.connStateMutex.Lock()
|
||||
defer c.connStateMutex.Unlock()
|
||||
c.connState = ConnectionStateWith0RTT{
|
||||
Used0RTT: c.used0RTT,
|
||||
ConnectionState: c.connectionStateLocked(),
|
||||
}
|
||||
}
|
||||
|
||||
// OCSPResponse returns the stapled OCSP response from the TLS server, if
|
||||
// any. (Only valid for client connections.)
|
||||
func (c *Conn) OCSPResponse() []byte {
|
||||
|
22
vendor/github.com/quic-go/qtls-go1-20/cpu.go
generated
vendored
22
vendor/github.com/quic-go/qtls-go1-20/cpu.go
generated
vendored
@@ -1,22 +0,0 @@
|
||||
//go:build !js
|
||||
// +build !js
|
||||
|
||||
package qtls
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"golang.org/x/sys/cpu"
|
||||
)
|
||||
|
||||
var (
|
||||
hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ
|
||||
hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL
|
||||
// Keep in sync with crypto/aes/cipher_s390x.go.
|
||||
hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR &&
|
||||
(cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM)
|
||||
|
||||
hasAESGCMHardwareSupport = runtime.GOARCH == "amd64" && hasGCMAsmAMD64 ||
|
||||
runtime.GOARCH == "arm64" && hasGCMAsmARM64 ||
|
||||
runtime.GOARCH == "s390x" && hasGCMAsmS390X
|
||||
)
|
12
vendor/github.com/quic-go/qtls-go1-20/cpu_other.go
generated
vendored
12
vendor/github.com/quic-go/qtls-go1-20/cpu_other.go
generated
vendored
@@ -1,12 +0,0 @@
|
||||
//go:build js
|
||||
// +build js
|
||||
|
||||
package qtls
|
||||
|
||||
var (
|
||||
hasGCMAsmAMD64 = false
|
||||
hasGCMAsmARM64 = false
|
||||
hasGCMAsmS390X = false
|
||||
|
||||
hasAESGCMHardwareSupport = false
|
||||
)
|
142
vendor/github.com/quic-go/qtls-go1-20/handshake_client.go
generated
vendored
142
vendor/github.com/quic-go/qtls-go1-20/handshake_client.go
generated
vendored
@@ -57,23 +57,12 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, clientKeySharePrivate, error)
|
||||
return nil, nil, errors.New("tls: NextProtos values too large")
|
||||
}
|
||||
|
||||
var supportedVersions []uint16
|
||||
var clientHelloVersion uint16
|
||||
if c.extraConfig.usesAlternativeRecordLayer() {
|
||||
if config.maxSupportedVersion(roleClient) < VersionTLS13 {
|
||||
return nil, nil, errors.New("tls: MaxVersion prevents QUIC from using TLS 1.3")
|
||||
}
|
||||
// Only offer TLS 1.3 when QUIC is used.
|
||||
supportedVersions = []uint16{VersionTLS13}
|
||||
clientHelloVersion = VersionTLS13
|
||||
} else {
|
||||
supportedVersions = config.supportedVersions(roleClient)
|
||||
if len(supportedVersions) == 0 {
|
||||
return nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion")
|
||||
}
|
||||
clientHelloVersion = config.maxSupportedVersion(roleClient)
|
||||
supportedVersions := config.supportedVersions(roleClient)
|
||||
if len(supportedVersions) == 0 {
|
||||
return nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion")
|
||||
}
|
||||
|
||||
clientHelloVersion := config.maxSupportedVersion(roleClient)
|
||||
// The version at the beginning of the ClientHello was capped at TLS 1.2
|
||||
// for compatibility reasons. The supported_versions extension is used
|
||||
// to negotiate versions now. See RFC 8446, Section 4.2.1.
|
||||
@@ -127,7 +116,9 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, clientKeySharePrivate, error)
|
||||
// A random session ID is used to detect when the server accepted a ticket
|
||||
// and is resuming a session (see RFC 5077). In TLS 1.3, it's always set as
|
||||
// a compatibility measure (see RFC 8446, Section 4.1.2).
|
||||
if c.extraConfig == nil || c.extraConfig.AlternativeRecordLayer == nil {
|
||||
//
|
||||
// The session ID is not set for QUIC connections (see RFC 9001, Section 8.4).
|
||||
if c.quic == nil {
|
||||
hello.sessionId = make([]byte, 32)
|
||||
if _, err := io.ReadFull(config.rand(), hello.sessionId); err != nil {
|
||||
return nil, nil, errors.New("tls: short read from Rand: " + err.Error())
|
||||
@@ -143,6 +134,9 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, clientKeySharePrivate, error)
|
||||
|
||||
var secret clientKeySharePrivate
|
||||
if hello.supportedVersions[0] == VersionTLS13 {
|
||||
if len(hello.supportedVersions) == 1 {
|
||||
hello.cipherSuites = hello.cipherSuites[:0]
|
||||
}
|
||||
if hasAESGCMHardwareSupport {
|
||||
hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13...)
|
||||
} else {
|
||||
@@ -176,8 +170,15 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, clientKeySharePrivate, error)
|
||||
}
|
||||
}
|
||||
|
||||
if hello.supportedVersions[0] == VersionTLS13 && c.extraConfig != nil && c.extraConfig.GetExtensions != nil {
|
||||
hello.additionalExtensions = c.extraConfig.GetExtensions(typeClientHello)
|
||||
if c.quic != nil {
|
||||
p, err := c.quicGetTransportParameters()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if p == nil {
|
||||
p = []byte{}
|
||||
}
|
||||
hello.quicTransportParameters = p
|
||||
}
|
||||
|
||||
return hello, secret, nil
|
||||
@@ -187,7 +188,6 @@ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
|
||||
if c.config == nil {
|
||||
c.config = fromConfig(defaultConfig())
|
||||
}
|
||||
c.setAlternativeRecordLayer()
|
||||
|
||||
// This may be a renegotiation handshake, in which case some fields
|
||||
// need to be reset.
|
||||
@@ -204,45 +204,33 @@ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
|
||||
return err
|
||||
}
|
||||
if cacheKey != "" && session != nil {
|
||||
var deletedTicket bool
|
||||
if session.vers == VersionTLS13 && hello.earlyData && c.extraConfig != nil && c.extraConfig.Enable0RTT {
|
||||
// don't reuse a session ticket that enabled 0-RTT
|
||||
c.config.ClientSessionCache.Put(cacheKey, nil)
|
||||
deletedTicket = true
|
||||
|
||||
if suite := cipherSuiteTLS13ByID(session.cipherSuite); suite != nil {
|
||||
h := suite.hash.New()
|
||||
helloBytes, err := hello.marshal()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
h.Write(helloBytes)
|
||||
clientEarlySecret := suite.deriveSecret(earlySecret, "c e traffic", h)
|
||||
c.out.exportKey(Encryption0RTT, suite, clientEarlySecret)
|
||||
if err := c.config.writeKeyLog(keyLogLabelEarlyTraffic, hello.random, clientEarlySecret); err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
// If we got a handshake failure when resuming a session, throw away
|
||||
// the session ticket. See RFC 5077, Section 3.2.
|
||||
//
|
||||
// RFC 8446 makes no mention of dropping tickets on failure, but it
|
||||
// does require servers to abort on invalid binders, so we need to
|
||||
// delete tickets to recover from a corrupted PSK.
|
||||
if err != nil {
|
||||
c.config.ClientSessionCache.Put(cacheKey, nil)
|
||||
}
|
||||
}
|
||||
if !deletedTicket {
|
||||
defer func() {
|
||||
// If we got a handshake failure when resuming a session, throw away
|
||||
// the session ticket. See RFC 5077, Section 3.2.
|
||||
//
|
||||
// RFC 8446 makes no mention of dropping tickets on failure, but it
|
||||
// does require servers to abort on invalid binders, so we need to
|
||||
// delete tickets to recover from a corrupted PSK.
|
||||
if err != nil {
|
||||
c.config.ClientSessionCache.Put(cacheKey, nil)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
if _, err := c.writeHandshakeRecord(hello, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if hello.earlyData {
|
||||
suite := cipherSuiteTLS13ByID(session.cipherSuite)
|
||||
transcript := suite.hash.New()
|
||||
if err := transcriptMsg(hello, transcript); err != nil {
|
||||
return err
|
||||
}
|
||||
earlyTrafficSecret := suite.deriveSecret(earlySecret, clientEarlyTrafficLabel, transcript)
|
||||
c.quicSetWriteSecret(QUICEncryptionLevelEarly, suite.id, earlyTrafficSecret)
|
||||
}
|
||||
|
||||
// serverHelloMsg is not included in the transcript
|
||||
msg, err := c.readHandshake(nil)
|
||||
if err != nil {
|
||||
@@ -305,7 +293,6 @@ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
|
||||
c.config.ClientSessionCache.Put(cacheKey, toClientSessionState(hs.session))
|
||||
}
|
||||
|
||||
c.updateConnectionState()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -358,7 +345,10 @@ func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string,
|
||||
}
|
||||
|
||||
// Try to resume a previously negotiated TLS session, if available.
|
||||
cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
|
||||
cacheKey = c.clientSessionCacheKey()
|
||||
if cacheKey == "" {
|
||||
return "", nil, nil, nil, nil
|
||||
}
|
||||
sess, ok := c.config.ClientSessionCache.Get(cacheKey)
|
||||
if !ok || sess == nil {
|
||||
return cacheKey, nil, nil, nil, nil
|
||||
@@ -442,6 +432,17 @@ func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string,
|
||||
return cacheKey, nil, nil, nil, nil
|
||||
}
|
||||
|
||||
if c.quic != nil && maxEarlyData > 0 {
|
||||
var earlyData bool
|
||||
if session.vers == VersionTLS13 && c.extraConfig != nil && c.extraConfig.SetAppDataFromSessionState != nil {
|
||||
earlyData = c.extraConfig.SetAppDataFromSessionState(appData)
|
||||
}
|
||||
// For 0-RTT, the cipher suite has to match exactly.
|
||||
if earlyData && mutualCipherSuiteTLS13(hello.cipherSuites, session.cipherSuite) != nil {
|
||||
hello.earlyData = true
|
||||
}
|
||||
}
|
||||
|
||||
// Set the pre_shared_key extension. See RFC 8446, Section 4.2.11.1.
|
||||
ticketAge := uint32(c.config.time().Sub(session.receivedAt) / time.Millisecond)
|
||||
identity := pskIdentity{
|
||||
@@ -456,9 +457,6 @@ func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string,
|
||||
session.nonce, cipherSuite.hash.Size())
|
||||
earlySecret = cipherSuite.extract(psk, nil)
|
||||
binderKey = cipherSuite.deriveSecret(earlySecret, resumptionBinderLabel, nil)
|
||||
if c.extraConfig != nil {
|
||||
hello.earlyData = c.extraConfig.Enable0RTT && maxEarlyData > 0
|
||||
}
|
||||
transcript := cipherSuite.hash.New()
|
||||
helloBytes, err := hello.marshalWithoutBinders()
|
||||
if err != nil {
|
||||
@@ -470,9 +468,6 @@ func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string,
|
||||
return "", nil, nil, nil, err
|
||||
}
|
||||
|
||||
if session.vers == VersionTLS13 && c.extraConfig != nil && c.extraConfig.SetAppDataFromSessionState != nil {
|
||||
c.extraConfig.SetAppDataFromSessionState(appData)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -827,7 +822,7 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if err := checkALPN(hs.hello.alpnProtocols, hs.serverHello.alpnProtocol); err != nil {
|
||||
if err := checkALPN(hs.hello.alpnProtocols, hs.serverHello.alpnProtocol, false); err != nil {
|
||||
c.sendAlert(alertUnsupportedExtension)
|
||||
return false, err
|
||||
}
|
||||
@@ -865,8 +860,12 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
|
||||
|
||||
// checkALPN ensure that the server's choice of ALPN protocol is compatible with
|
||||
// the protocols that we advertised in the Client Hello.
|
||||
func checkALPN(clientProtos []string, serverProto string) error {
|
||||
func checkALPN(clientProtos []string, serverProto string, quic bool) error {
|
||||
if serverProto == "" {
|
||||
if quic && len(clientProtos) > 0 {
|
||||
// RFC 9001, Section 8.1
|
||||
return errors.New("tls: server did not select an ALPN protocol")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if len(clientProtos) == 0 {
|
||||
@@ -962,6 +961,10 @@ func (hs *clientHandshakeState) sendFinished(out []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// maxRSAKeySize is the maximum RSA key size in bits that we are willing
|
||||
// to verify the signatures of during a TLS handshake.
|
||||
const maxRSAKeySize = 8192
|
||||
|
||||
// verifyServerCertificate parses and verifies the provided chain, setting
|
||||
// c.verifiedChains and c.peerCertificates or sending the appropriate alert.
|
||||
func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
|
||||
@@ -973,6 +976,10 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
|
||||
c.sendAlert(alertBadCertificate)
|
||||
return errors.New("tls: failed to parse certificate from server: " + err.Error())
|
||||
}
|
||||
if cert.cert.PublicKeyAlgorithm == x509.RSA && cert.cert.PublicKey.(*rsa.PublicKey).N.BitLen() > maxRSAKeySize {
|
||||
c.sendAlert(alertBadCertificate)
|
||||
return fmt.Errorf("tls: server sent certificate containing RSA key larger than %d bits", maxRSAKeySize)
|
||||
}
|
||||
activeHandles[i] = cert
|
||||
certs[i] = cert.cert
|
||||
}
|
||||
@@ -1106,15 +1113,16 @@ func (c *Conn) getClientCertificate(cri *CertificateRequestInfo) (*Certificate,
|
||||
return new(Certificate), nil
|
||||
}
|
||||
|
||||
const clientSessionCacheKeyPrefix = "qtls-"
|
||||
|
||||
// clientSessionCacheKey returns a key used to cache sessionTickets that could
|
||||
// be used to resume previously negotiated TLS sessions with a server.
|
||||
func clientSessionCacheKey(serverAddr net.Addr, config *config) string {
|
||||
if len(config.ServerName) > 0 {
|
||||
return clientSessionCacheKeyPrefix + config.ServerName
|
||||
func (c *Conn) clientSessionCacheKey() string {
|
||||
if len(c.config.ServerName) > 0 {
|
||||
return c.config.ServerName
|
||||
}
|
||||
return clientSessionCacheKeyPrefix + serverAddr.String()
|
||||
if c.conn != nil {
|
||||
return c.conn.RemoteAddr().String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// hostnameInSNI converts name into an appropriate hostname for SNI.
|
||||
|
86
vendor/github.com/quic-go/qtls-go1-20/handshake_client_tls13.go
generated
vendored
86
vendor/github.com/quic-go/qtls-go1-20/handshake_client_tls13.go
generated
vendored
@@ -91,7 +91,6 @@ func (hs *clientHandshakeStateTLS13) handshake() error {
|
||||
if err := hs.processServerHello(); err != nil {
|
||||
return err
|
||||
}
|
||||
c.updateConnectionState()
|
||||
if err := hs.sendDummyChangeCipherSpec(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -104,7 +103,6 @@ func (hs *clientHandshakeStateTLS13) handshake() error {
|
||||
if err := hs.readServerCertificate(); err != nil {
|
||||
return err
|
||||
}
|
||||
c.updateConnectionState()
|
||||
if err := hs.readServerFinished(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -125,7 +123,7 @@ func (hs *clientHandshakeStateTLS13) handshake() error {
|
||||
})
|
||||
|
||||
c.isHandshakeComplete.Store(true)
|
||||
c.updateConnectionState()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -187,6 +185,9 @@ func (hs *clientHandshakeStateTLS13) checkServerHelloOrHRR() error {
|
||||
// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility
|
||||
// with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4.
|
||||
func (hs *clientHandshakeStateTLS13) sendDummyChangeCipherSpec() error {
|
||||
if hs.c.quic != nil {
|
||||
return nil
|
||||
}
|
||||
if hs.sentDummyCCS {
|
||||
return nil
|
||||
}
|
||||
@@ -293,7 +294,7 @@ func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
|
||||
transcript := hs.suite.hash.New()
|
||||
transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
|
||||
transcript.Write(chHash)
|
||||
if err := transcriptMsg(hs.serverHello, hs.transcript); err != nil {
|
||||
if err := transcriptMsg(hs.serverHello, transcript); err != nil {
|
||||
return err
|
||||
}
|
||||
helloBytes, err := hs.hello.marshalWithoutBinders()
|
||||
@@ -312,10 +313,11 @@ func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
|
||||
}
|
||||
}
|
||||
|
||||
if hs.hello.earlyData && c.extraConfig != nil && c.extraConfig.Rejected0RTT != nil {
|
||||
c.extraConfig.Rejected0RTT()
|
||||
if hs.hello.earlyData {
|
||||
hs.hello.earlyData = false
|
||||
c.quicRejectedEarlyData()
|
||||
}
|
||||
hs.hello.earlyData = false // disable 0-RTT
|
||||
|
||||
if _, err := hs.c.writeHandshakeRecord(hs.hello, hs.transcript); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -430,12 +432,18 @@ func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
|
||||
|
||||
clientSecret := hs.suite.deriveSecret(handshakeSecret,
|
||||
clientHandshakeTrafficLabel, hs.transcript)
|
||||
c.out.exportKey(EncryptionHandshake, hs.suite, clientSecret)
|
||||
c.out.setTrafficSecret(hs.suite, clientSecret)
|
||||
c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, clientSecret)
|
||||
serverSecret := hs.suite.deriveSecret(handshakeSecret,
|
||||
serverHandshakeTrafficLabel, hs.transcript)
|
||||
c.in.exportKey(EncryptionHandshake, hs.suite, serverSecret)
|
||||
c.in.setTrafficSecret(hs.suite, serverSecret)
|
||||
c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, serverSecret)
|
||||
|
||||
if c.quic != nil {
|
||||
if c.hand.Len() != 0 {
|
||||
c.sendAlert(alertUnexpectedMessage)
|
||||
}
|
||||
c.quicSetWriteSecret(QUICEncryptionLevelHandshake, hs.suite.id, clientSecret)
|
||||
c.quicSetReadSecret(QUICEncryptionLevelHandshake, hs.suite.id, serverSecret)
|
||||
}
|
||||
|
||||
err = c.config.writeKeyLog(keyLogLabelClientHandshake, hs.hello.random, clientSecret)
|
||||
if err != nil {
|
||||
@@ -467,28 +475,35 @@ func (hs *clientHandshakeStateTLS13) readServerParameters() error {
|
||||
c.sendAlert(alertUnexpectedMessage)
|
||||
return unexpectedMessageError(encryptedExtensions, msg)
|
||||
}
|
||||
// Notify the caller if 0-RTT was rejected.
|
||||
if !encryptedExtensions.earlyData && hs.hello.earlyData && c.extraConfig != nil && c.extraConfig.Rejected0RTT != nil {
|
||||
c.extraConfig.Rejected0RTT()
|
||||
}
|
||||
c.used0RTT = encryptedExtensions.earlyData
|
||||
if hs.c.extraConfig != nil && hs.c.extraConfig.ReceivedExtensions != nil {
|
||||
hs.c.extraConfig.ReceivedExtensions(typeEncryptedExtensions, encryptedExtensions.additionalExtensions)
|
||||
}
|
||||
|
||||
if err := checkALPN(hs.hello.alpnProtocols, encryptedExtensions.alpnProtocol); err != nil {
|
||||
c.sendAlert(alertUnsupportedExtension)
|
||||
if err := checkALPN(hs.hello.alpnProtocols, encryptedExtensions.alpnProtocol, c.quic != nil); err != nil {
|
||||
// RFC 8446 specifies that no_application_protocol is sent by servers, but
|
||||
// does not specify how clients handle the selection of an incompatible protocol.
|
||||
// RFC 9001 Section 8.1 specifies that QUIC clients send no_application_protocol
|
||||
// in this case. Always sending no_application_protocol seems reasonable.
|
||||
c.sendAlert(alertNoApplicationProtocol)
|
||||
return err
|
||||
}
|
||||
c.clientProtocol = encryptedExtensions.alpnProtocol
|
||||
|
||||
if c.extraConfig != nil && c.extraConfig.EnforceNextProtoSelection {
|
||||
if len(encryptedExtensions.alpnProtocol) == 0 {
|
||||
// the server didn't select an ALPN
|
||||
c.sendAlert(alertNoApplicationProtocol)
|
||||
return errors.New("ALPN negotiation failed. Server didn't offer any protocols")
|
||||
if c.quic != nil {
|
||||
if encryptedExtensions.quicTransportParameters == nil {
|
||||
// RFC 9001 Section 8.2.
|
||||
c.sendAlert(alertMissingExtension)
|
||||
return errors.New("tls: server did not send a quic_transport_parameters extension")
|
||||
}
|
||||
c.quicSetTransportParameters(encryptedExtensions.quicTransportParameters)
|
||||
} else {
|
||||
if encryptedExtensions.quicTransportParameters != nil {
|
||||
c.sendAlert(alertUnsupportedExtension)
|
||||
return errors.New("tls: server sent an unexpected quic_transport_parameters extension")
|
||||
}
|
||||
}
|
||||
|
||||
if hs.hello.earlyData && !encryptedExtensions.earlyData {
|
||||
c.quicRejectedEarlyData()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -616,8 +631,7 @@ func (hs *clientHandshakeStateTLS13) readServerFinished() error {
|
||||
clientApplicationTrafficLabel, hs.transcript)
|
||||
serverSecret := hs.suite.deriveSecret(hs.masterSecret,
|
||||
serverApplicationTrafficLabel, hs.transcript)
|
||||
c.in.exportKey(EncryptionApplication, hs.suite, serverSecret)
|
||||
c.in.setTrafficSecret(hs.suite, serverSecret)
|
||||
c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, serverSecret)
|
||||
|
||||
err = c.config.writeKeyLog(keyLogLabelClientTraffic, hs.hello.random, hs.trafficSecret)
|
||||
if err != nil {
|
||||
@@ -713,14 +727,20 @@ func (hs *clientHandshakeStateTLS13) sendClientFinished() error {
|
||||
return err
|
||||
}
|
||||
|
||||
c.out.exportKey(EncryptionApplication, hs.suite, hs.trafficSecret)
|
||||
c.out.setTrafficSecret(hs.suite, hs.trafficSecret)
|
||||
c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, hs.trafficSecret)
|
||||
|
||||
if !c.config.SessionTicketsDisabled && c.config.ClientSessionCache != nil {
|
||||
c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret,
|
||||
resumptionLabel, hs.transcript)
|
||||
}
|
||||
|
||||
if c.quic != nil {
|
||||
if c.hand.Len() != 0 {
|
||||
c.sendAlert(alertUnexpectedMessage)
|
||||
}
|
||||
c.quicSetWriteSecret(QUICEncryptionLevelApplication, hs.suite.id, hs.trafficSecret)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -791,8 +811,10 @@ func (c *Conn) handleNewSessionTicket(msg *newSessionTicketMsgTLS13) error {
|
||||
scts: c.scts,
|
||||
}
|
||||
|
||||
cacheKey := clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
|
||||
c.config.ClientSessionCache.Put(cacheKey, toClientSessionState(session))
|
||||
cacheKey := c.clientSessionCacheKey()
|
||||
if cacheKey != "" {
|
||||
c.config.ClientSessionCache.Put(cacheKey, toClientSessionState(session))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
51
vendor/github.com/quic-go/qtls-go1-20/handshake_messages.go
generated
vendored
51
vendor/github.com/quic-go/qtls-go1-20/handshake_messages.go
generated
vendored
@@ -93,7 +93,7 @@ type clientHelloMsg struct {
|
||||
pskModes []uint8
|
||||
pskIdentities []pskIdentity
|
||||
pskBinders [][]byte
|
||||
additionalExtensions []Extension
|
||||
quicTransportParameters []byte
|
||||
}
|
||||
|
||||
func (m *clientHelloMsg) marshal() ([]byte, error) {
|
||||
@@ -247,10 +247,11 @@ func (m *clientHelloMsg) marshal() ([]byte, error) {
|
||||
})
|
||||
})
|
||||
}
|
||||
for _, ext := range m.additionalExtensions {
|
||||
exts.AddUint16(ext.Type)
|
||||
if m.quicTransportParameters != nil { // marshal zero-length parameters when present
|
||||
// RFC 9001, Section 8.2
|
||||
exts.AddUint16(extensionQUICTransportParameters)
|
||||
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
|
||||
exts.AddBytes(ext.Data)
|
||||
exts.AddBytes(m.quicTransportParameters)
|
||||
})
|
||||
}
|
||||
if len(m.pskIdentities) > 0 { // pre_shared_key must be the last extension
|
||||
@@ -567,6 +568,11 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
|
||||
if !readUint8LengthPrefixed(&extData, &m.pskModes) {
|
||||
return false
|
||||
}
|
||||
case extensionQUICTransportParameters:
|
||||
m.quicTransportParameters = make([]byte, len(extData))
|
||||
if !extData.CopyBytes(m.quicTransportParameters) {
|
||||
return false
|
||||
}
|
||||
case extensionPreSharedKey:
|
||||
// RFC 8446, Section 4.2.11
|
||||
if !extensions.Empty() {
|
||||
@@ -598,7 +604,7 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
|
||||
m.pskBinders = append(m.pskBinders, binder)
|
||||
}
|
||||
default:
|
||||
m.additionalExtensions = append(m.additionalExtensions, Extension{Type: extension, Data: extData})
|
||||
// Ignore unknown extensions.
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -867,11 +873,10 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
|
||||
}
|
||||
|
||||
type encryptedExtensionsMsg struct {
|
||||
raw []byte
|
||||
alpnProtocol string
|
||||
earlyData bool
|
||||
|
||||
additionalExtensions []Extension
|
||||
raw []byte
|
||||
alpnProtocol string
|
||||
quicTransportParameters []byte
|
||||
earlyData bool
|
||||
}
|
||||
|
||||
func (m *encryptedExtensionsMsg) marshal() ([]byte, error) {
|
||||
@@ -893,17 +898,18 @@ func (m *encryptedExtensionsMsg) marshal() ([]byte, error) {
|
||||
})
|
||||
})
|
||||
}
|
||||
if m.quicTransportParameters != nil { // marshal zero-length parameters when present
|
||||
// draft-ietf-quic-tls-32, Section 8.2
|
||||
b.AddUint16(extensionQUICTransportParameters)
|
||||
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
|
||||
b.AddBytes(m.quicTransportParameters)
|
||||
})
|
||||
}
|
||||
if m.earlyData {
|
||||
// RFC 8446, Section 4.2.10
|
||||
b.AddUint16(extensionEarlyData)
|
||||
b.AddUint16(0) // empty extension_data
|
||||
}
|
||||
for _, ext := range m.additionalExtensions {
|
||||
b.AddUint16(ext.Type)
|
||||
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
|
||||
b.AddBytes(ext.Data)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -923,14 +929,14 @@ func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
|
||||
}
|
||||
|
||||
for !extensions.Empty() {
|
||||
var ext uint16
|
||||
var extension uint16
|
||||
var extData cryptobyte.String
|
||||
if !extensions.ReadUint16(&ext) ||
|
||||
if !extensions.ReadUint16(&extension) ||
|
||||
!extensions.ReadUint16LengthPrefixed(&extData) {
|
||||
return false
|
||||
}
|
||||
|
||||
switch ext {
|
||||
switch extension {
|
||||
case extensionALPN:
|
||||
var protoList cryptobyte.String
|
||||
if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {
|
||||
@@ -942,10 +948,15 @@ func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
|
||||
return false
|
||||
}
|
||||
m.alpnProtocol = string(proto)
|
||||
case extensionQUICTransportParameters:
|
||||
m.quicTransportParameters = make([]byte, len(extData))
|
||||
if !extData.CopyBytes(m.quicTransportParameters) {
|
||||
return false
|
||||
}
|
||||
case extensionEarlyData:
|
||||
m.earlyData = true
|
||||
default:
|
||||
m.additionalExtensions = append(m.additionalExtensions, Extension{Type: ext, Data: extData})
|
||||
// Ignore unknown extensions.
|
||||
continue
|
||||
}
|
||||
|
||||
|
42
vendor/github.com/quic-go/qtls-go1-20/handshake_server.go
generated
vendored
42
vendor/github.com/quic-go/qtls-go1-20/handshake_server.go
generated
vendored
@@ -39,8 +39,6 @@ type serverHandshakeState struct {
|
||||
|
||||
// serverHandshake performs a TLS handshake as a server.
|
||||
func (c *Conn) serverHandshake(ctx context.Context) error {
|
||||
c.setAlternativeRecordLayer()
|
||||
|
||||
clientHello, err := c.readClientHello(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -53,12 +51,6 @@ func (c *Conn) serverHandshake(ctx context.Context) error {
|
||||
clientHello: clientHello,
|
||||
}
|
||||
return hs.handshake()
|
||||
} else if c.extraConfig.usesAlternativeRecordLayer() {
|
||||
// This should already have been caught by the check that the ClientHello doesn't
|
||||
// offer any (supported) versions older than TLS 1.3.
|
||||
// Check again to make sure we can't be tricked into using an older version.
|
||||
c.sendAlert(alertProtocolVersion)
|
||||
return errors.New("tls: negotiated TLS < 1.3 when using QUIC")
|
||||
}
|
||||
|
||||
hs := serverHandshakeState{
|
||||
@@ -131,7 +123,6 @@ func (hs *serverHandshakeState) handshake() error {
|
||||
c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random)
|
||||
c.isHandshakeComplete.Store(true)
|
||||
|
||||
c.updateConnectionState()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -167,27 +158,6 @@ func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, error) {
|
||||
if len(clientHello.supportedVersions) == 0 {
|
||||
clientVersions = supportedVersionsFromMax(clientHello.vers)
|
||||
}
|
||||
if c.extraConfig.usesAlternativeRecordLayer() {
|
||||
// In QUIC, the client MUST NOT offer any old TLS versions.
|
||||
// Here, we can only check that none of the other supported versions of this library
|
||||
// (TLS 1.0 - TLS 1.2) is offered. We don't check for any SSL versions here.
|
||||
for _, ver := range clientVersions {
|
||||
if ver == VersionTLS13 {
|
||||
continue
|
||||
}
|
||||
for _, v := range supportedVersions {
|
||||
if ver == v {
|
||||
c.sendAlert(alertProtocolVersion)
|
||||
return nil, fmt.Errorf("tls: client offered old TLS version %#x", ver)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Make the config we're using allows us to use TLS 1.3.
|
||||
if c.config.maxSupportedVersion(roleServer) < VersionTLS13 {
|
||||
c.sendAlert(alertInternalError)
|
||||
return nil, errors.New("tls: MaxVersion prevents QUIC from using TLS 1.3")
|
||||
}
|
||||
}
|
||||
c.vers, ok = c.config.mutualVersion(roleServer, clientVersions)
|
||||
if !ok {
|
||||
c.sendAlert(alertProtocolVersion)
|
||||
@@ -249,7 +219,7 @@ func (hs *serverHandshakeState) processClientHello() error {
|
||||
c.serverName = hs.clientHello.serverName
|
||||
}
|
||||
|
||||
selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols)
|
||||
selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols, false)
|
||||
if err != nil {
|
||||
c.sendAlert(alertNoApplicationProtocol)
|
||||
return err
|
||||
@@ -310,8 +280,12 @@ func (hs *serverHandshakeState) processClientHello() error {
|
||||
// negotiateALPN picks a shared ALPN protocol that both sides support in server
|
||||
// preference order. If ALPN is not configured or the peer doesn't support it,
|
||||
// it returns "" and no error.
|
||||
func negotiateALPN(serverProtos, clientProtos []string) (string, error) {
|
||||
func negotiateALPN(serverProtos, clientProtos []string, quic bool) (string, error) {
|
||||
if len(serverProtos) == 0 || len(clientProtos) == 0 {
|
||||
if quic && len(serverProtos) != 0 {
|
||||
// RFC 9001, Section 8.1
|
||||
return "", fmt.Errorf("tls: client did not request an application protocol")
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
var http11fallback bool
|
||||
@@ -849,6 +823,10 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error {
|
||||
c.sendAlert(alertBadCertificate)
|
||||
return errors.New("tls: failed to parse client certificate: " + err.Error())
|
||||
}
|
||||
if certs[i].PublicKeyAlgorithm == x509.RSA && certs[i].PublicKey.(*rsa.PublicKey).N.BitLen() > maxRSAKeySize {
|
||||
c.sendAlert(alertBadCertificate)
|
||||
return fmt.Errorf("tls: client sent certificate containing RSA key larger than %d bits", maxRSAKeySize)
|
||||
}
|
||||
}
|
||||
|
||||
if len(certs) == 0 && requiresClientCert(c.config.ClientAuth) {
|
||||
|
170
vendor/github.com/quic-go/qtls-go1-20/handshake_server_tls13.go
generated
vendored
170
vendor/github.com/quic-go/qtls-go1-20/handshake_server_tls13.go
generated
vendored
@@ -41,6 +41,7 @@ type serverHandshakeStateTLS13 struct {
|
||||
trafficSecret []byte // client_application_traffic_secret_0
|
||||
transcript hash.Hash
|
||||
clientFinished []byte
|
||||
earlyData bool
|
||||
}
|
||||
|
||||
func (hs *serverHandshakeStateTLS13) handshake() error {
|
||||
@@ -59,7 +60,6 @@ func (hs *serverHandshakeStateTLS13) handshake() error {
|
||||
if err := hs.checkForResumption(); err != nil {
|
||||
return err
|
||||
}
|
||||
c.updateConnectionState()
|
||||
if err := hs.pickCertificate(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -82,7 +82,6 @@ func (hs *serverHandshakeStateTLS13) handshake() error {
|
||||
if err := hs.readClientCertificate(); err != nil {
|
||||
return err
|
||||
}
|
||||
c.updateConnectionState()
|
||||
if err := hs.readClientFinished(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -94,7 +93,7 @@ func (hs *serverHandshakeStateTLS13) handshake() error {
|
||||
})
|
||||
|
||||
c.isHandshakeComplete.Store(true)
|
||||
c.updateConnectionState()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -236,13 +235,23 @@ GroupSelection:
|
||||
return errors.New("tls: invalid client key share")
|
||||
}
|
||||
|
||||
c.serverName = hs.clientHello.serverName
|
||||
|
||||
if c.extraConfig != nil && c.extraConfig.ReceivedExtensions != nil {
|
||||
c.extraConfig.ReceivedExtensions(typeClientHello, hs.clientHello.additionalExtensions)
|
||||
if c.quic != nil {
|
||||
if hs.clientHello.quicTransportParameters == nil {
|
||||
// RFC 9001 Section 8.2.
|
||||
c.sendAlert(alertMissingExtension)
|
||||
return errors.New("tls: client did not send a quic_transport_parameters extension")
|
||||
}
|
||||
c.quicSetTransportParameters(hs.clientHello.quicTransportParameters)
|
||||
} else {
|
||||
if hs.clientHello.quicTransportParameters != nil {
|
||||
c.sendAlert(alertUnsupportedExtension)
|
||||
return errors.New("tls: client sent an unexpected quic_transport_parameters extension")
|
||||
}
|
||||
}
|
||||
|
||||
selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols)
|
||||
c.serverName = hs.clientHello.serverName
|
||||
|
||||
selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols, c.quic != nil)
|
||||
if err != nil {
|
||||
hs.alpnNegotiationErr = err
|
||||
}
|
||||
@@ -299,10 +308,9 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error {
|
||||
}
|
||||
|
||||
if hs.alpnNegotiationErr == nil && sessionState.alpn == c.clientProtocol &&
|
||||
c.extraConfig != nil && c.extraConfig.MaxEarlyData > 0 &&
|
||||
c.extraConfig != nil && c.extraConfig.Enable0RTT &&
|
||||
c.extraConfig.Accept0RTT != nil && c.extraConfig.Accept0RTT(sessionState.appData) {
|
||||
hs.encryptedExtensions.earlyData = true
|
||||
c.used0RTT = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,27 +362,23 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error {
|
||||
return errors.New("tls: invalid PSK binder")
|
||||
}
|
||||
|
||||
if c.quic != nil && hs.clientHello.earlyData && hs.encryptedExtensions.earlyData && i == 0 &&
|
||||
sessionState.maxEarlyData > 0 && sessionState.cipherSuite == hs.suite.id {
|
||||
hs.earlyData = true
|
||||
|
||||
transcript := hs.suite.hash.New()
|
||||
if err := transcriptMsg(hs.clientHello, transcript); err != nil {
|
||||
return err
|
||||
}
|
||||
earlyTrafficSecret := hs.suite.deriveSecret(hs.earlySecret, clientEarlyTrafficLabel, transcript)
|
||||
c.quicSetReadSecret(QUICEncryptionLevelEarly, hs.suite.id, earlyTrafficSecret)
|
||||
}
|
||||
|
||||
c.didResume = true
|
||||
if err := c.processCertsFromClient(sessionState.certificate); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
h := cloneHash(hs.transcript, hs.suite.hash)
|
||||
clientHelloWithBindersBytes, err := hs.clientHello.marshal()
|
||||
if err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return err
|
||||
}
|
||||
h.Write(clientHelloWithBindersBytes)
|
||||
if hs.encryptedExtensions.earlyData {
|
||||
clientEarlySecret := hs.suite.deriveSecret(hs.earlySecret, "c e traffic", h)
|
||||
c.in.exportKey(Encryption0RTT, hs.suite, clientEarlySecret)
|
||||
if err := c.config.writeKeyLog(keyLogLabelEarlyTraffic, hs.clientHello.random, clientEarlySecret); err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
hs.hello.selectedIdentityPresent = true
|
||||
hs.hello.selectedIdentity = uint16(i)
|
||||
hs.usingPSK = true
|
||||
@@ -449,6 +453,9 @@ func (hs *serverHandshakeStateTLS13) pickCertificate() error {
|
||||
// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility
|
||||
// with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4.
|
||||
func (hs *serverHandshakeStateTLS13) sendDummyChangeCipherSpec() error {
|
||||
if hs.c.quic != nil {
|
||||
return nil
|
||||
}
|
||||
if hs.sentDummyCCS {
|
||||
return nil
|
||||
}
|
||||
@@ -517,9 +524,9 @@ func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup CurveID)
|
||||
return errors.New("tls: client illegally modified second ClientHello")
|
||||
}
|
||||
|
||||
if clientHello.earlyData {
|
||||
if illegalClientHelloChange(clientHello, hs.clientHello) {
|
||||
c.sendAlert(alertIllegalParameter)
|
||||
return errors.New("tls: client offered 0-RTT data in second ClientHello")
|
||||
return errors.New("tls: client illegally modified second ClientHello")
|
||||
}
|
||||
|
||||
hs.clientHello = clientHello
|
||||
@@ -607,12 +614,18 @@ func (hs *serverHandshakeStateTLS13) sendServerParameters() error {
|
||||
|
||||
clientSecret := hs.suite.deriveSecret(hs.handshakeSecret,
|
||||
clientHandshakeTrafficLabel, hs.transcript)
|
||||
c.in.exportKey(EncryptionHandshake, hs.suite, clientSecret)
|
||||
c.in.setTrafficSecret(hs.suite, clientSecret)
|
||||
c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, clientSecret)
|
||||
serverSecret := hs.suite.deriveSecret(hs.handshakeSecret,
|
||||
serverHandshakeTrafficLabel, hs.transcript)
|
||||
c.out.exportKey(EncryptionHandshake, hs.suite, serverSecret)
|
||||
c.out.setTrafficSecret(hs.suite, serverSecret)
|
||||
c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, serverSecret)
|
||||
|
||||
if c.quic != nil {
|
||||
if c.hand.Len() != 0 {
|
||||
c.sendAlert(alertUnexpectedMessage)
|
||||
}
|
||||
c.quicSetWriteSecret(QUICEncryptionLevelHandshake, hs.suite.id, serverSecret)
|
||||
c.quicSetReadSecret(QUICEncryptionLevelHandshake, hs.suite.id, clientSecret)
|
||||
}
|
||||
|
||||
err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.clientHello.random, clientSecret)
|
||||
if err != nil {
|
||||
@@ -625,12 +638,20 @@ func (hs *serverHandshakeStateTLS13) sendServerParameters() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if hs.alpnNegotiationErr != nil {
|
||||
selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols, c.quic != nil)
|
||||
if err != nil {
|
||||
c.sendAlert(alertNoApplicationProtocol)
|
||||
return hs.alpnNegotiationErr
|
||||
return err
|
||||
}
|
||||
if hs.c.extraConfig != nil && hs.c.extraConfig.GetExtensions != nil {
|
||||
hs.encryptedExtensions.additionalExtensions = hs.c.extraConfig.GetExtensions(typeEncryptedExtensions)
|
||||
hs.encryptedExtensions.alpnProtocol = selectedProto
|
||||
c.clientProtocol = selectedProto
|
||||
|
||||
if c.quic != nil {
|
||||
p, err := c.quicGetTransportParameters()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hs.encryptedExtensions.quicTransportParameters = p
|
||||
}
|
||||
|
||||
if _, err := hs.c.writeHandshakeRecord(hs.encryptedExtensions, hs.transcript); err != nil {
|
||||
@@ -731,8 +752,15 @@ func (hs *serverHandshakeStateTLS13) sendServerFinished() error {
|
||||
clientApplicationTrafficLabel, hs.transcript)
|
||||
serverSecret := hs.suite.deriveSecret(hs.masterSecret,
|
||||
serverApplicationTrafficLabel, hs.transcript)
|
||||
c.out.exportKey(EncryptionApplication, hs.suite, serverSecret)
|
||||
c.out.setTrafficSecret(hs.suite, serverSecret)
|
||||
c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, serverSecret)
|
||||
|
||||
if c.quic != nil {
|
||||
if c.hand.Len() != 0 {
|
||||
// TODO: Handle this in setTrafficSecret?
|
||||
c.sendAlert(alertUnexpectedMessage)
|
||||
}
|
||||
c.quicSetWriteSecret(QUICEncryptionLevelApplication, hs.suite.id, serverSecret)
|
||||
}
|
||||
|
||||
err := c.config.writeKeyLog(keyLogLabelClientTraffic, hs.clientHello.random, hs.trafficSecret)
|
||||
if err != nil {
|
||||
@@ -764,6 +792,10 @@ func (hs *serverHandshakeStateTLS13) shouldSendSessionTickets() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// QUIC tickets are sent by QUICConn.SendSessionTicket, not automatically.
|
||||
if hs.c.quic != nil {
|
||||
return false
|
||||
}
|
||||
// Don't send tickets the client wouldn't use. See RFC 8446, Section 4.2.9.
|
||||
for _, pskMode := range hs.clientHello.pskModes {
|
||||
if pskMode == pskModeDHE {
|
||||
@@ -783,25 +815,66 @@ func (hs *serverHandshakeStateTLS13) sendSessionTickets() error {
|
||||
if err := transcriptMsg(finishedMsg, hs.transcript); err != nil {
|
||||
return err
|
||||
}
|
||||
c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret,
|
||||
resumptionLabel, hs.transcript)
|
||||
|
||||
if !hs.shouldSendSessionTickets() {
|
||||
return nil
|
||||
}
|
||||
return c.sendSessionTicket(false)
|
||||
}
|
||||
|
||||
c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret,
|
||||
resumptionLabel, hs.transcript)
|
||||
|
||||
// Don't send session tickets when the alternative record layer is set.
|
||||
// Instead, save the resumption secret on the Conn.
|
||||
// Session tickets can then be generated by calling Conn.GetSessionTicket().
|
||||
if hs.c.extraConfig != nil && hs.c.extraConfig.AlternativeRecordLayer != nil {
|
||||
return nil
|
||||
func (c *Conn) sendSessionTicket(earlyData bool) error {
|
||||
suite := cipherSuiteTLS13ByID(c.cipherSuite)
|
||||
if suite == nil {
|
||||
return errors.New("tls: internal error: unknown cipher suite")
|
||||
}
|
||||
|
||||
m, err := hs.c.getSessionTicketMsg(nil)
|
||||
m := new(newSessionTicketMsgTLS13)
|
||||
|
||||
var certsFromClient [][]byte
|
||||
for _, cert := range c.peerCertificates {
|
||||
certsFromClient = append(certsFromClient, cert.Raw)
|
||||
}
|
||||
state := sessionStateTLS13{
|
||||
cipherSuite: suite.id,
|
||||
createdAt: uint64(c.config.time().Unix()),
|
||||
resumptionSecret: c.resumptionSecret,
|
||||
certificate: Certificate{
|
||||
Certificate: certsFromClient,
|
||||
OCSPStaple: c.ocspResponse,
|
||||
SignedCertificateTimestamps: c.scts,
|
||||
},
|
||||
alpn: c.clientProtocol,
|
||||
}
|
||||
if earlyData {
|
||||
state.maxEarlyData = 0xffffffff
|
||||
state.appData = c.extraConfig.GetAppDataForSessionTicket()
|
||||
}
|
||||
stateBytes, err := state.marshal()
|
||||
if err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return err
|
||||
}
|
||||
m.label, err = c.encryptTicket(stateBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.lifetime = uint32(maxSessionTicketLifetime / time.Second)
|
||||
|
||||
// ticket_age_add is a random 32-bit value. See RFC 8446, section 4.6.1
|
||||
// The value is not stored anywhere; we never need to check the ticket age
|
||||
// because 0-RTT is not supported.
|
||||
ageAdd := make([]byte, 4)
|
||||
_, err = c.config.rand().Read(ageAdd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if earlyData {
|
||||
// RFC 9001, Section 4.6.1
|
||||
m.maxEarlyData = 0xffffffff
|
||||
}
|
||||
|
||||
if _, err := c.writeHandshakeRecord(m, nil); err != nil {
|
||||
return err
|
||||
@@ -919,8 +992,7 @@ func (hs *serverHandshakeStateTLS13) readClientFinished() error {
|
||||
return errors.New("tls: invalid client finished hash")
|
||||
}
|
||||
|
||||
c.in.exportKey(EncryptionApplication, hs.suite, hs.trafficSecret)
|
||||
c.in.setTrafficSecret(hs.suite, hs.trafficSecret)
|
||||
c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, hs.trafficSecret)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
1
vendor/github.com/quic-go/qtls-go1-20/key_schedule.go
generated
vendored
1
vendor/github.com/quic-go/qtls-go1-20/key_schedule.go
generated
vendored
@@ -21,6 +21,7 @@ import (
|
||||
|
||||
const (
|
||||
resumptionBinderLabel = "res binder"
|
||||
clientEarlyTrafficLabel = "c e traffic"
|
||||
clientHandshakeTrafficLabel = "c hs traffic"
|
||||
serverHandshakeTrafficLabel = "s hs traffic"
|
||||
clientApplicationTrafficLabel = "c ap traffic"
|
||||
|
418
vendor/github.com/quic-go/qtls-go1-20/quic.go
generated
vendored
Normal file
418
vendor/github.com/quic-go/qtls-go1-20/quic.go
generated
vendored
Normal file
@@ -0,0 +1,418 @@
|
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package qtls
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// QUICEncryptionLevel represents a QUIC encryption level used to transmit
|
||||
// handshake messages.
|
||||
type QUICEncryptionLevel int
|
||||
|
||||
const (
|
||||
QUICEncryptionLevelInitial = QUICEncryptionLevel(iota)
|
||||
QUICEncryptionLevelEarly
|
||||
QUICEncryptionLevelHandshake
|
||||
QUICEncryptionLevelApplication
|
||||
)
|
||||
|
||||
func (l QUICEncryptionLevel) String() string {
|
||||
switch l {
|
||||
case QUICEncryptionLevelInitial:
|
||||
return "Initial"
|
||||
case QUICEncryptionLevelEarly:
|
||||
return "Early"
|
||||
case QUICEncryptionLevelHandshake:
|
||||
return "Handshake"
|
||||
case QUICEncryptionLevelApplication:
|
||||
return "Application"
|
||||
default:
|
||||
return fmt.Sprintf("QUICEncryptionLevel(%v)", int(l))
|
||||
}
|
||||
}
|
||||
|
||||
// A QUICConn represents a connection which uses a QUIC implementation as the underlying
|
||||
// transport as described in RFC 9001.
|
||||
//
|
||||
// Methods of QUICConn are not safe for concurrent use.
|
||||
type QUICConn struct {
|
||||
conn *Conn
|
||||
|
||||
sessionTicketSent bool
|
||||
}
|
||||
|
||||
// A QUICConfig configures a QUICConn.
|
||||
type QUICConfig struct {
|
||||
TLSConfig *Config
|
||||
ExtraConfig *ExtraConfig
|
||||
}
|
||||
|
||||
// A QUICEventKind is a type of operation on a QUIC connection.
|
||||
type QUICEventKind int
|
||||
|
||||
const (
|
||||
// QUICNoEvent indicates that there are no events available.
|
||||
QUICNoEvent QUICEventKind = iota
|
||||
|
||||
// QUICSetReadSecret and QUICSetWriteSecret provide the read and write
|
||||
// secrets for a given encryption level.
|
||||
// QUICEvent.Level, QUICEvent.Data, and QUICEvent.Suite are set.
|
||||
//
|
||||
// Secrets for the Initial encryption level are derived from the initial
|
||||
// destination connection ID, and are not provided by the QUICConn.
|
||||
QUICSetReadSecret
|
||||
QUICSetWriteSecret
|
||||
|
||||
// QUICWriteData provides data to send to the peer in CRYPTO frames.
|
||||
// QUICEvent.Data is set.
|
||||
QUICWriteData
|
||||
|
||||
// QUICTransportParameters provides the peer's QUIC transport parameters.
|
||||
// QUICEvent.Data is set.
|
||||
QUICTransportParameters
|
||||
|
||||
// QUICTransportParametersRequired indicates that the caller must provide
|
||||
// QUIC transport parameters to send to the peer. The caller should set
|
||||
// the transport parameters with QUICConn.SetTransportParameters and call
|
||||
// QUICConn.NextEvent again.
|
||||
//
|
||||
// If transport parameters are set before calling QUICConn.Start, the
|
||||
// connection will never generate a QUICTransportParametersRequired event.
|
||||
QUICTransportParametersRequired
|
||||
|
||||
// QUICRejectedEarlyData indicates that the server rejected 0-RTT data even
|
||||
// if we offered it. It's returned before QUICEncryptionLevelApplication
|
||||
// keys are returned.
|
||||
QUICRejectedEarlyData
|
||||
|
||||
// QUICHandshakeDone indicates that the TLS handshake has completed.
|
||||
QUICHandshakeDone
|
||||
)
|
||||
|
||||
// A QUICEvent is an event occurring on a QUIC connection.
|
||||
//
|
||||
// The type of event is specified by the Kind field.
|
||||
// The contents of the other fields are kind-specific.
|
||||
type QUICEvent struct {
|
||||
Kind QUICEventKind
|
||||
|
||||
// Set for QUICSetReadSecret, QUICSetWriteSecret, and QUICWriteData.
|
||||
Level QUICEncryptionLevel
|
||||
|
||||
// Set for QUICTransportParameters, QUICSetReadSecret, QUICSetWriteSecret, and QUICWriteData.
|
||||
// The contents are owned by crypto/tls, and are valid until the next NextEvent call.
|
||||
Data []byte
|
||||
|
||||
// Set for QUICSetReadSecret and QUICSetWriteSecret.
|
||||
Suite uint16
|
||||
}
|
||||
|
||||
type quicState struct {
|
||||
events []QUICEvent
|
||||
nextEvent int
|
||||
|
||||
// eventArr is a statically allocated event array, large enough to handle
|
||||
// the usual maximum number of events resulting from a single call: transport
|
||||
// parameters, Initial data, Early read secret, Handshake write and read
|
||||
// secrets, Handshake data, Application write secret, Application data.
|
||||
eventArr [8]QUICEvent
|
||||
|
||||
started bool
|
||||
signalc chan struct{} // handshake data is available to be read
|
||||
blockedc chan struct{} // handshake is waiting for data, closed when done
|
||||
cancelc <-chan struct{} // handshake has been canceled
|
||||
cancel context.CancelFunc
|
||||
|
||||
// readbuf is shared between HandleData and the handshake goroutine.
|
||||
// HandshakeCryptoData passes ownership to the handshake goroutine by
|
||||
// reading from signalc, and reclaims ownership by reading from blockedc.
|
||||
readbuf []byte
|
||||
|
||||
transportParams []byte // to send to the peer
|
||||
}
|
||||
|
||||
// QUICClient returns a new TLS client side connection using QUICTransport as the
|
||||
// underlying transport. The config cannot be nil.
|
||||
//
|
||||
// The config's MinVersion must be at least TLS 1.3.
|
||||
func QUICClient(config *QUICConfig) *QUICConn {
|
||||
return newQUICConn(Client(nil, config.TLSConfig), config.ExtraConfig)
|
||||
}
|
||||
|
||||
// QUICServer returns a new TLS server side connection using QUICTransport as the
|
||||
// underlying transport. The config cannot be nil.
|
||||
//
|
||||
// The config's MinVersion must be at least TLS 1.3.
|
||||
func QUICServer(config *QUICConfig) *QUICConn {
|
||||
return newQUICConn(Server(nil, config.TLSConfig), config.ExtraConfig)
|
||||
}
|
||||
|
||||
func newQUICConn(conn *Conn, extraConfig *ExtraConfig) *QUICConn {
|
||||
conn.quic = &quicState{
|
||||
signalc: make(chan struct{}),
|
||||
blockedc: make(chan struct{}),
|
||||
}
|
||||
conn.quic.events = conn.quic.eventArr[:0]
|
||||
conn.extraConfig = extraConfig
|
||||
return &QUICConn{
|
||||
conn: conn,
|
||||
}
|
||||
}
|
||||
|
||||
// Start starts the client or server handshake protocol.
|
||||
// It may produce connection events, which may be read with NextEvent.
|
||||
//
|
||||
// Start must be called at most once.
|
||||
func (q *QUICConn) Start(ctx context.Context) error {
|
||||
if q.conn.quic.started {
|
||||
return quicError(errors.New("tls: Start called more than once"))
|
||||
}
|
||||
q.conn.quic.started = true
|
||||
if q.conn.config.MinVersion < VersionTLS13 {
|
||||
return quicError(errors.New("tls: Config MinVersion must be at least TLS 1.13"))
|
||||
}
|
||||
go q.conn.HandshakeContext(ctx)
|
||||
if _, ok := <-q.conn.quic.blockedc; !ok {
|
||||
return q.conn.handshakeErr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NextEvent returns the next event occurring on the connection.
|
||||
// It returns an event with a Kind of QUICNoEvent when no events are available.
|
||||
func (q *QUICConn) NextEvent() QUICEvent {
|
||||
qs := q.conn.quic
|
||||
if last := qs.nextEvent - 1; last >= 0 && len(qs.events[last].Data) > 0 {
|
||||
// Write over some of the previous event's data,
|
||||
// to catch callers erroniously retaining it.
|
||||
qs.events[last].Data[0] = 0
|
||||
}
|
||||
if qs.nextEvent >= len(qs.events) {
|
||||
qs.events = qs.events[:0]
|
||||
qs.nextEvent = 0
|
||||
return QUICEvent{Kind: QUICNoEvent}
|
||||
}
|
||||
e := qs.events[qs.nextEvent]
|
||||
qs.events[qs.nextEvent] = QUICEvent{} // zero out references to data
|
||||
qs.nextEvent++
|
||||
return e
|
||||
}
|
||||
|
||||
// Close closes the connection and stops any in-progress handshake.
|
||||
func (q *QUICConn) Close() error {
|
||||
if q.conn.quic.cancel == nil {
|
||||
return nil // never started
|
||||
}
|
||||
q.conn.quic.cancel()
|
||||
for range q.conn.quic.blockedc {
|
||||
// Wait for the handshake goroutine to return.
|
||||
}
|
||||
return q.conn.handshakeErr
|
||||
}
|
||||
|
||||
// HandleData handles handshake bytes received from the peer.
|
||||
// It may produce connection events, which may be read with NextEvent.
|
||||
func (q *QUICConn) HandleData(level QUICEncryptionLevel, data []byte) error {
|
||||
c := q.conn
|
||||
if c.in.level != level {
|
||||
return quicError(c.in.setErrorLocked(errors.New("tls: handshake data received at wrong level")))
|
||||
}
|
||||
c.quic.readbuf = data
|
||||
<-c.quic.signalc
|
||||
_, ok := <-c.quic.blockedc
|
||||
if ok {
|
||||
// The handshake goroutine is waiting for more data.
|
||||
return nil
|
||||
}
|
||||
// The handshake goroutine has exited.
|
||||
c.handshakeMutex.Lock()
|
||||
defer c.handshakeMutex.Unlock()
|
||||
c.hand.Write(c.quic.readbuf)
|
||||
c.quic.readbuf = nil
|
||||
for q.conn.hand.Len() >= 4 && q.conn.handshakeErr == nil {
|
||||
b := q.conn.hand.Bytes()
|
||||
n := int(b[1])<<16 | int(b[2])<<8 | int(b[3])
|
||||
if n > maxHandshake {
|
||||
q.conn.handshakeErr = fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake)
|
||||
break
|
||||
}
|
||||
if len(b) < 4+n {
|
||||
return nil
|
||||
}
|
||||
if err := q.conn.handlePostHandshakeMessage(); err != nil {
|
||||
q.conn.handshakeErr = err
|
||||
}
|
||||
}
|
||||
if q.conn.handshakeErr != nil {
|
||||
return quicError(q.conn.handshakeErr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SendSessionTicket sends a session ticket to the client.
|
||||
// It produces connection events, which may be read with NextEvent.
|
||||
// Currently, it can only be called once.
|
||||
func (q *QUICConn) SendSessionTicket(earlyData bool) error {
|
||||
c := q.conn
|
||||
if !c.isHandshakeComplete.Load() {
|
||||
return quicError(errors.New("tls: SendSessionTicket called before handshake completed"))
|
||||
}
|
||||
if c.isClient {
|
||||
return quicError(errors.New("tls: SendSessionTicket called on the client"))
|
||||
}
|
||||
if q.sessionTicketSent {
|
||||
return quicError(errors.New("tls: SendSessionTicket called multiple times"))
|
||||
}
|
||||
q.sessionTicketSent = true
|
||||
return quicError(c.sendSessionTicket(earlyData))
|
||||
}
|
||||
|
||||
// ConnectionState returns basic TLS details about the connection.
|
||||
func (q *QUICConn) ConnectionState() ConnectionState {
|
||||
return q.conn.ConnectionState()
|
||||
}
|
||||
|
||||
// SetTransportParameters sets the transport parameters to send to the peer.
|
||||
//
|
||||
// Server connections may delay setting the transport parameters until after
|
||||
// receiving the client's transport parameters. See QUICTransportParametersRequired.
|
||||
func (q *QUICConn) SetTransportParameters(params []byte) {
|
||||
if params == nil {
|
||||
params = []byte{}
|
||||
}
|
||||
q.conn.quic.transportParams = params
|
||||
if q.conn.quic.started {
|
||||
<-q.conn.quic.signalc
|
||||
<-q.conn.quic.blockedc
|
||||
}
|
||||
}
|
||||
|
||||
// quicError ensures err is an AlertError.
|
||||
// If err is not already, quicError wraps it with alertInternalError.
|
||||
func quicError(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
var ae AlertError
|
||||
if errors.As(err, &ae) {
|
||||
return err
|
||||
}
|
||||
var a alert
|
||||
if !errors.As(err, &a) {
|
||||
a = alertInternalError
|
||||
}
|
||||
// Return an error wrapping the original error and an AlertError.
|
||||
// Truncate the text of the alert to 0 characters.
|
||||
return fmt.Errorf("%w%.0w", err, AlertError(a))
|
||||
}
|
||||
|
||||
func (c *Conn) quicReadHandshakeBytes(n int) error {
|
||||
for c.hand.Len() < n {
|
||||
if err := c.quicWaitForSignal(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Conn) quicSetReadSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
|
||||
c.quic.events = append(c.quic.events, QUICEvent{
|
||||
Kind: QUICSetReadSecret,
|
||||
Level: level,
|
||||
Suite: suite,
|
||||
Data: secret,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *Conn) quicSetWriteSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
|
||||
c.quic.events = append(c.quic.events, QUICEvent{
|
||||
Kind: QUICSetWriteSecret,
|
||||
Level: level,
|
||||
Suite: suite,
|
||||
Data: secret,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *Conn) quicWriteCryptoData(level QUICEncryptionLevel, data []byte) {
|
||||
var last *QUICEvent
|
||||
if len(c.quic.events) > 0 {
|
||||
last = &c.quic.events[len(c.quic.events)-1]
|
||||
}
|
||||
if last == nil || last.Kind != QUICWriteData || last.Level != level {
|
||||
c.quic.events = append(c.quic.events, QUICEvent{
|
||||
Kind: QUICWriteData,
|
||||
Level: level,
|
||||
})
|
||||
last = &c.quic.events[len(c.quic.events)-1]
|
||||
}
|
||||
last.Data = append(last.Data, data...)
|
||||
}
|
||||
|
||||
func (c *Conn) quicSetTransportParameters(params []byte) {
|
||||
c.quic.events = append(c.quic.events, QUICEvent{
|
||||
Kind: QUICTransportParameters,
|
||||
Data: params,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *Conn) quicGetTransportParameters() ([]byte, error) {
|
||||
if c.quic.transportParams == nil {
|
||||
c.quic.events = append(c.quic.events, QUICEvent{
|
||||
Kind: QUICTransportParametersRequired,
|
||||
})
|
||||
}
|
||||
for c.quic.transportParams == nil {
|
||||
if err := c.quicWaitForSignal(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return c.quic.transportParams, nil
|
||||
}
|
||||
|
||||
func (c *Conn) quicHandshakeComplete() {
|
||||
c.quic.events = append(c.quic.events, QUICEvent{
|
||||
Kind: QUICHandshakeDone,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *Conn) quicRejectedEarlyData() {
|
||||
c.quic.events = append(c.quic.events, QUICEvent{
|
||||
Kind: QUICRejectedEarlyData,
|
||||
})
|
||||
}
|
||||
|
||||
// quicWaitForSignal notifies the QUICConn that handshake progress is blocked,
|
||||
// and waits for a signal that the handshake should proceed.
|
||||
//
|
||||
// The handshake may become blocked waiting for handshake bytes
|
||||
// or for the user to provide transport parameters.
|
||||
func (c *Conn) quicWaitForSignal() error {
|
||||
// Drop the handshake mutex while blocked to allow the user
|
||||
// to call ConnectionState before the handshake completes.
|
||||
c.handshakeMutex.Unlock()
|
||||
defer c.handshakeMutex.Lock()
|
||||
// Send on blockedc to notify the QUICConn that the handshake is blocked.
|
||||
// Exported methods of QUICConn wait for the handshake to become blocked
|
||||
// before returning to the user.
|
||||
select {
|
||||
case c.quic.blockedc <- struct{}{}:
|
||||
case <-c.quic.cancelc:
|
||||
return c.sendAlertLocked(alertCloseNotify)
|
||||
}
|
||||
// The QUICConn reads from signalc to notify us that the handshake may
|
||||
// be able to proceed. (The QUICConn reads, because we close signalc to
|
||||
// indicate that the handshake has completed.)
|
||||
select {
|
||||
case c.quic.signalc <- struct{}{}:
|
||||
c.hand.Write(c.quic.readbuf)
|
||||
c.quic.readbuf = nil
|
||||
case <-c.quic.cancelc:
|
||||
return c.sendAlertLocked(alertCloseNotify)
|
||||
}
|
||||
return nil
|
||||
}
|
76
vendor/github.com/quic-go/qtls-go1-20/ticket.go
generated
vendored
76
vendor/github.com/quic-go/qtls-go1-20/ticket.go
generated
vendored
@@ -11,12 +11,9 @@ import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"crypto/subtle"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/cryptobyte"
|
||||
"io"
|
||||
)
|
||||
|
||||
// sessionState contains the information that is serialized into a session
|
||||
@@ -204,74 +201,3 @@ func (c *Conn) decryptTicket(encrypted []byte) (plaintext []byte, usedOldKey boo
|
||||
|
||||
return plaintext, keyIndex > 0
|
||||
}
|
||||
|
||||
func (c *Conn) getSessionTicketMsg(appData []byte) (*newSessionTicketMsgTLS13, error) {
|
||||
m := new(newSessionTicketMsgTLS13)
|
||||
|
||||
var certsFromClient [][]byte
|
||||
for _, cert := range c.peerCertificates {
|
||||
certsFromClient = append(certsFromClient, cert.Raw)
|
||||
}
|
||||
state := sessionStateTLS13{
|
||||
cipherSuite: c.cipherSuite,
|
||||
createdAt: uint64(c.config.time().Unix()),
|
||||
resumptionSecret: c.resumptionSecret,
|
||||
certificate: Certificate{
|
||||
Certificate: certsFromClient,
|
||||
OCSPStaple: c.ocspResponse,
|
||||
SignedCertificateTimestamps: c.scts,
|
||||
},
|
||||
appData: appData,
|
||||
alpn: c.clientProtocol,
|
||||
}
|
||||
if c.extraConfig != nil {
|
||||
state.maxEarlyData = c.extraConfig.MaxEarlyData
|
||||
}
|
||||
stateBytes, err := state.marshal()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m.label, err = c.encryptTicket(stateBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m.lifetime = uint32(maxSessionTicketLifetime / time.Second)
|
||||
|
||||
// ticket_age_add is a random 32-bit value. See RFC 8446, section 4.6.1
|
||||
// The value is not stored anywhere; we never need to check the ticket age
|
||||
// because 0-RTT is not supported.
|
||||
ageAdd := make([]byte, 4)
|
||||
_, err = c.config.rand().Read(ageAdd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m.ageAdd = binary.LittleEndian.Uint32(ageAdd)
|
||||
|
||||
// ticket_nonce, which must be unique per connection, is always left at
|
||||
// zero because we only ever send one ticket per connection.
|
||||
|
||||
if c.extraConfig != nil {
|
||||
m.maxEarlyData = c.extraConfig.MaxEarlyData
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// GetSessionTicket generates a new session ticket.
|
||||
// It should only be called after the handshake completes.
|
||||
// It can only be used for servers, and only if the alternative record layer is set.
|
||||
// The ticket may be nil if config.SessionTicketsDisabled is set,
|
||||
// or if the client isn't able to receive session tickets.
|
||||
func (c *Conn) GetSessionTicket(appData []byte) ([]byte, error) {
|
||||
if c.isClient || !c.isHandshakeComplete.Load() || c.extraConfig == nil || c.extraConfig.AlternativeRecordLayer == nil {
|
||||
return nil, errors.New("GetSessionTicket is only valid for servers after completion of the handshake, and if an alternative record layer is set.")
|
||||
}
|
||||
if c.config.SessionTicketsDisabled {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
m, err := c.getSessionTicketMsg(appData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m.marshal()
|
||||
}
|
||||
|
44
vendor/github.com/quic-go/qtls-go1-20/tls.go
generated
vendored
44
vendor/github.com/quic-go/qtls-go1-20/tls.go
generated
vendored
@@ -31,11 +31,10 @@ import (
|
||||
// using conn as the underlying transport.
|
||||
// The configuration config must be non-nil and must include
|
||||
// at least one certificate or else set GetCertificate.
|
||||
func Server(conn net.Conn, config *Config, extraConfig *ExtraConfig) *Conn {
|
||||
func Server(conn net.Conn, config *Config) *Conn {
|
||||
c := &Conn{
|
||||
conn: conn,
|
||||
config: fromConfig(config),
|
||||
extraConfig: extraConfig,
|
||||
conn: conn,
|
||||
config: fromConfig(config),
|
||||
}
|
||||
c.handshakeFn = c.serverHandshake
|
||||
return c
|
||||
@@ -45,12 +44,11 @@ func Server(conn net.Conn, config *Config, extraConfig *ExtraConfig) *Conn {
|
||||
// using conn as the underlying transport.
|
||||
// The config cannot be nil: users must set either ServerName or
|
||||
// InsecureSkipVerify in the config.
|
||||
func Client(conn net.Conn, config *Config, extraConfig *ExtraConfig) *Conn {
|
||||
func Client(conn net.Conn, config *Config) *Conn {
|
||||
c := &Conn{
|
||||
conn: conn,
|
||||
config: fromConfig(config),
|
||||
extraConfig: extraConfig,
|
||||
isClient: true,
|
||||
conn: conn,
|
||||
config: fromConfig(config),
|
||||
isClient: true,
|
||||
}
|
||||
c.handshakeFn = c.clientHandshake
|
||||
return c
|
||||
@@ -59,8 +57,7 @@ func Client(conn net.Conn, config *Config, extraConfig *ExtraConfig) *Conn {
|
||||
// A listener implements a network listener (net.Listener) for TLS connections.
|
||||
type listener struct {
|
||||
net.Listener
|
||||
config *Config
|
||||
extraConfig *ExtraConfig
|
||||
config *Config
|
||||
}
|
||||
|
||||
// Accept waits for and returns the next incoming TLS connection.
|
||||
@@ -70,18 +67,17 @@ func (l *listener) Accept() (net.Conn, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Server(c, l.config, l.extraConfig), nil
|
||||
return Server(c, l.config), nil
|
||||
}
|
||||
|
||||
// NewListener creates a Listener which accepts connections from an inner
|
||||
// Listener and wraps each connection with Server.
|
||||
// The configuration config must be non-nil and must include
|
||||
// at least one certificate or else set GetCertificate.
|
||||
func NewListener(inner net.Listener, config *Config, extraConfig *ExtraConfig) net.Listener {
|
||||
func NewListener(inner net.Listener, config *Config) net.Listener {
|
||||
l := new(listener)
|
||||
l.Listener = inner
|
||||
l.config = config
|
||||
l.extraConfig = extraConfig
|
||||
return l
|
||||
}
|
||||
|
||||
@@ -89,7 +85,7 @@ func NewListener(inner net.Listener, config *Config, extraConfig *ExtraConfig) n
|
||||
// given network address using net.Listen.
|
||||
// The configuration config must be non-nil and must include
|
||||
// at least one certificate or else set GetCertificate.
|
||||
func Listen(network, laddr string, config *Config, extraConfig *ExtraConfig) (net.Listener, error) {
|
||||
func Listen(network, laddr string, config *Config) (net.Listener, error) {
|
||||
if config == nil || len(config.Certificates) == 0 &&
|
||||
config.GetCertificate == nil && config.GetConfigForClient == nil {
|
||||
return nil, errors.New("tls: neither Certificates, GetCertificate, nor GetConfigForClient set in Config")
|
||||
@@ -98,7 +94,7 @@ func Listen(network, laddr string, config *Config, extraConfig *ExtraConfig) (ne
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewListener(l, config, extraConfig), nil
|
||||
return NewListener(l, config), nil
|
||||
}
|
||||
|
||||
type timeoutError struct{}
|
||||
@@ -117,11 +113,11 @@ func (timeoutError) Temporary() bool { return true }
|
||||
//
|
||||
// DialWithDialer uses context.Background internally; to specify the context,
|
||||
// use Dialer.DialContext with NetDialer set to the desired dialer.
|
||||
func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config, extraConfig *ExtraConfig) (*Conn, error) {
|
||||
return dial(context.Background(), dialer, network, addr, config, extraConfig)
|
||||
func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error) {
|
||||
return dial(context.Background(), dialer, network, addr, config)
|
||||
}
|
||||
|
||||
func dial(ctx context.Context, netDialer *net.Dialer, network, addr string, config *Config, extraConfig *ExtraConfig) (*Conn, error) {
|
||||
func dial(ctx context.Context, netDialer *net.Dialer, network, addr string, config *Config) (*Conn, error) {
|
||||
if netDialer.Timeout != 0 {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithTimeout(ctx, netDialer.Timeout)
|
||||
@@ -157,7 +153,7 @@ func dial(ctx context.Context, netDialer *net.Dialer, network, addr string, conf
|
||||
config = c
|
||||
}
|
||||
|
||||
conn := Client(rawConn, config, extraConfig)
|
||||
conn := Client(rawConn, config)
|
||||
if err := conn.HandshakeContext(ctx); err != nil {
|
||||
rawConn.Close()
|
||||
return nil, err
|
||||
@@ -171,8 +167,8 @@ func dial(ctx context.Context, netDialer *net.Dialer, network, addr string, conf
|
||||
// Dial interprets a nil configuration as equivalent to
|
||||
// the zero configuration; see the documentation of Config
|
||||
// for the defaults.
|
||||
func Dial(network, addr string, config *Config, extraConfig *ExtraConfig) (*Conn, error) {
|
||||
return DialWithDialer(new(net.Dialer), network, addr, config, extraConfig)
|
||||
func Dial(network, addr string, config *Config) (*Conn, error) {
|
||||
return DialWithDialer(new(net.Dialer), network, addr, config)
|
||||
}
|
||||
|
||||
// Dialer dials TLS connections given a configuration and a Dialer for the
|
||||
@@ -188,8 +184,6 @@ type Dialer struct {
|
||||
// configuration; see the documentation of Config for the
|
||||
// defaults.
|
||||
Config *Config
|
||||
|
||||
ExtraConfig *ExtraConfig
|
||||
}
|
||||
|
||||
// Dial connects to the given network address and initiates a TLS
|
||||
@@ -220,7 +214,7 @@ func (d *Dialer) netDialer() *net.Dialer {
|
||||
//
|
||||
// The returned Conn, if any, will always be of type *Conn.
|
||||
func (d *Dialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
c, err := dial(ctx, d.netDialer(), network, addr, d.Config, d.ExtraConfig)
|
||||
c, err := dial(ctx, d.netDialer(), network, addr, d.Config)
|
||||
if err != nil {
|
||||
// Don't return c (a typed nil) in an interface.
|
||||
return nil, err
|
||||
|
5
vendor/github.com/quic-go/qtls-go1-20/unsafe.go
generated
vendored
5
vendor/github.com/quic-go/qtls-go1-20/unsafe.go
generated
vendored
@@ -94,3 +94,8 @@ func compareStruct(a, b reflect.Type) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// InitSessionTicketKeys triggers the initialization of session ticket keys.
|
||||
func InitSessionTicketKeys(conf *Config) {
|
||||
fromConfig(conf).ticketKeys(nil)
|
||||
}
|
||||
|
Reference in New Issue
Block a user