forked from quic-go/quic-go
update to qtls based on Go 1.14's TLS implementation
This commit is contained in:
@@ -103,7 +103,7 @@ var _ = Describe("Crypto Setup TLS", func() {
|
||||
Expect(getCertificateErr).To(MatchError("GetCertificate"))
|
||||
_, getClientCertificateErr := qtlsConf.GetClientCertificate(nil)
|
||||
Expect(getClientCertificateErr).To(MatchError("GetClientCertificate"))
|
||||
cconf, err := qtlsConf.GetConfigForClient(&tls.ClientHelloInfo{ServerName: "foo.bar"})
|
||||
cconf, err := qtlsConf.GetConfigForClient(&qtls.ClientHelloInfo{ServerName: "foo.bar"})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(cconf.ServerName).To(Equal("foo.bar"))
|
||||
Expect(cconf.AlternativeRecordLayer).ToNot(BeNil())
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/marten-seemann/qtls"
|
||||
|
||||
@@ -58,10 +59,10 @@ func tlsConfigToQtlsConfig(
|
||||
if maxVersion < qtls.VersionTLS13 {
|
||||
maxVersion = qtls.VersionTLS13
|
||||
}
|
||||
var getConfigForClient func(ch *tls.ClientHelloInfo) (*qtls.Config, error)
|
||||
var getConfigForClient func(ch *qtls.ClientHelloInfo) (*qtls.Config, error)
|
||||
if c.GetConfigForClient != nil {
|
||||
getConfigForClient = func(ch *tls.ClientHelloInfo) (*qtls.Config, error) {
|
||||
tlsConf, err := c.GetConfigForClient(ch)
|
||||
getConfigForClient = func(ch *qtls.ClientHelloInfo) (*qtls.Config, error) {
|
||||
tlsConf, err := c.GetConfigForClient((*tls.ClientHelloInfo)(unsafe.Pointer(ch)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -78,12 +79,12 @@ func tlsConfigToQtlsConfig(
|
||||
conf := &qtls.Config{
|
||||
Rand: c.Rand,
|
||||
Time: c.Time,
|
||||
Certificates: c.Certificates,
|
||||
Certificates: *(*[]qtls.Certificate)(unsafe.Pointer(&c.Certificates)),
|
||||
// NameToCertificate is deprecated, but we still need to copy it if the user sets it.
|
||||
//nolint:staticcheck
|
||||
NameToCertificate: c.NameToCertificate,
|
||||
GetCertificate: c.GetCertificate,
|
||||
GetClientCertificate: c.GetClientCertificate,
|
||||
NameToCertificate: *(*map[string]*qtls.Certificate)(unsafe.Pointer(&c.NameToCertificate)),
|
||||
GetCertificate: *(*func(*qtls.ClientHelloInfo) (*qtls.Certificate, error))(unsafe.Pointer(&c.GetCertificate)),
|
||||
GetClientCertificate: *(*func(*qtls.CertificateRequestInfo) (*qtls.Certificate, error))(unsafe.Pointer(&c.GetClientCertificate)),
|
||||
GetConfigForClient: getConfigForClient,
|
||||
VerifyPeerCertificate: c.VerifyPeerCertificate,
|
||||
RootCAs: c.RootCAs,
|
||||
@@ -117,6 +118,18 @@ func tlsConfigToQtlsConfig(
|
||||
return conf
|
||||
}
|
||||
|
||||
// qtlsConfigToTLSConfig is used to transform a qtls.Config to a tls.Config.
|
||||
// It is used to create the tls.Config in the ClientHelloInfo.
|
||||
// It doesn't copy all values, but only those used by ClientHelloInfo.SupportsCertificate.
|
||||
func qtlsConfigToTLSConfig(config *qtls.Config) *tls.Config {
|
||||
return &tls.Config{
|
||||
MinVersion: config.MinVersion,
|
||||
MaxVersion: config.MaxVersion,
|
||||
CipherSuites: config.CipherSuites,
|
||||
CurvePreferences: config.CurvePreferences,
|
||||
}
|
||||
}
|
||||
|
||||
func cipherSuiteName(id uint16) string {
|
||||
switch id {
|
||||
case qtls.TLS_AES_128_GCM_SHA256:
|
||||
|
||||
@@ -1,24 +1,41 @@
|
||||
package handshake
|
||||
|
||||
// This package uses unsafe to convert between:
|
||||
// * qtls.Certificate and tls.Certificate
|
||||
// * qtls.CertificateRequestInfo and tls.CertificateRequestInfo
|
||||
// * qtls.ClientHelloInfo and tls.ClientHelloInfo
|
||||
// * qtls.ConnectionState and tls.ConnectionState
|
||||
// * qtls.ClientSessionState and tls.ClientSessionState
|
||||
// We check in init() that this conversion actually is safe.
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"github.com/marten-seemann/qtls"
|
||||
)
|
||||
|
||||
func init() {
|
||||
if !structsEqual(&tls.Certificate{}, &qtls.Certificate{}) {
|
||||
panic("qtls.Certificate not compatible with tls.Certificate")
|
||||
}
|
||||
if !structsEqual(&tls.CertificateRequestInfo{}, &qtls.CertificateRequestInfo{}) {
|
||||
panic("qtls.CertificateRequestInfo not compatible with tls.CertificateRequestInfo")
|
||||
}
|
||||
if !structsEqual(&tls.ClientSessionState{}, &qtls.ClientSessionState{}) {
|
||||
panic("qtls.ClientSessionState not compatible with tls.ClientSessionState")
|
||||
}
|
||||
if !structsEqual(&tls.ClientSessionState{}, &clientSessionState{}) {
|
||||
panic("clientSessionState not compatible with tls.ClientSessionState")
|
||||
}
|
||||
if !structsEqual(&tls.ClientHelloInfo{}, &clientHelloInfo{}) {
|
||||
panic("clientHelloInfo not compatible with tls.ClientHelloInfo")
|
||||
}
|
||||
if !structsEqual(&qtls.ClientHelloInfo{}, &qtlsClientHelloInfo{}) {
|
||||
panic("qtlsClientHelloInfo not compatible with qtls.ClientHelloInfo")
|
||||
}
|
||||
}
|
||||
|
||||
func structsEqual(a, b interface{}) bool {
|
||||
@@ -36,3 +53,44 @@ func structsEqual(a, b interface{}) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
type clientHelloInfo struct {
|
||||
CipherSuites []uint16
|
||||
ServerName string
|
||||
SupportedCurves []tls.CurveID
|
||||
SupportedPoints []uint8
|
||||
SignatureSchemes []tls.SignatureScheme
|
||||
SupportedProtos []string
|
||||
SupportedVersions []uint16
|
||||
Conn net.Conn
|
||||
|
||||
config *tls.Config
|
||||
}
|
||||
|
||||
type qtlsClientHelloInfo struct {
|
||||
CipherSuites []uint16
|
||||
ServerName string
|
||||
SupportedCurves []tls.CurveID
|
||||
SupportedPoints []uint8
|
||||
SignatureSchemes []tls.SignatureScheme
|
||||
SupportedProtos []string
|
||||
SupportedVersions []uint16
|
||||
Conn net.Conn
|
||||
|
||||
config *qtls.Config
|
||||
}
|
||||
|
||||
func toTLSClientHelloInfo(chi *qtls.ClientHelloInfo) *tls.ClientHelloInfo {
|
||||
qtlsCHI := (*qtlsClientHelloInfo)(unsafe.Pointer(chi))
|
||||
return (*tls.ClientHelloInfo)(unsafe.Pointer(&clientHelloInfo{
|
||||
CipherSuites: chi.CipherSuites,
|
||||
ServerName: chi.ServerName,
|
||||
SupportedCurves: chi.SupportedCurves,
|
||||
SupportedPoints: chi.SupportedPoints,
|
||||
SignatureSchemes: chi.SignatureSchemes,
|
||||
SupportedProtos: chi.SupportedProtos,
|
||||
SupportedVersions: chi.SupportedVersions,
|
||||
Conn: chi.Conn,
|
||||
config: qtlsConfigToTLSConfig((*qtls.Config)(unsafe.Pointer(qtlsCHI.config))),
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
package handshake
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"unsafe"
|
||||
|
||||
"github.com/marten-seemann/qtls"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
@@ -57,4 +62,37 @@ var _ = Describe("Unsafe checks", func() {
|
||||
Expect(structsEqual(&target{}, &interchangedFields{})).To(BeFalse())
|
||||
Expect(structsEqual(&target{}, &renamedCallbackFunctionParams{})).To(BeTrue())
|
||||
})
|
||||
|
||||
It("converts a qtls.ClientHelloInfo to a tls.ClientHelloInfo", func() {
|
||||
chi := &qtlsClientHelloInfo{
|
||||
CipherSuites: []uint16{1, 2, 3},
|
||||
ServerName: "foo.bar",
|
||||
SupportedCurves: []qtls.CurveID{4, 5, 6},
|
||||
SupportedPoints: []uint8{7, 8, 9},
|
||||
SignatureSchemes: []qtls.SignatureScheme{10, 11, 12},
|
||||
SupportedProtos: []string{"foo", "bar"},
|
||||
SupportedVersions: []uint16{13, 14, 15},
|
||||
Conn: &net.UDPConn{},
|
||||
config: &qtls.Config{
|
||||
MinVersion: tls.VersionTLS10,
|
||||
MaxVersion: tls.VersionTLS12,
|
||||
CipherSuites: []uint16{16, 17, 18},
|
||||
CurvePreferences: []qtls.CurveID{19, 20, 21},
|
||||
},
|
||||
}
|
||||
tlsCHI := toTLSClientHelloInfo((*qtls.ClientHelloInfo)(unsafe.Pointer(chi)))
|
||||
Expect(tlsCHI.CipherSuites).To(Equal([]uint16{1, 2, 3}))
|
||||
Expect(tlsCHI.ServerName).To(Equal("foo.bar"))
|
||||
Expect(tlsCHI.SupportedCurves).To(Equal([]tls.CurveID{4, 5, 6}))
|
||||
Expect(tlsCHI.SupportedPoints).To(Equal([]uint8{7, 8, 9}))
|
||||
Expect(tlsCHI.SignatureSchemes).To(Equal([]tls.SignatureScheme{10, 11, 12}))
|
||||
Expect(tlsCHI.SupportedProtos).To(Equal([]string{"foo", "bar"}))
|
||||
Expect(tlsCHI.SupportedVersions).To(Equal([]uint16{13, 14, 15}))
|
||||
Expect(tlsCHI.Conn).To(Equal(&net.UDPConn{}))
|
||||
c := (*clientHelloInfo)(unsafe.Pointer(tlsCHI))
|
||||
Expect(c.config.CipherSuites).To(Equal([]uint16{16, 17, 18}))
|
||||
Expect(c.config.MinVersion).To(BeEquivalentTo(tls.VersionTLS10))
|
||||
Expect(c.config.MaxVersion).To(BeEquivalentTo(tls.VersionTLS12))
|
||||
Expect(c.config.CurvePreferences).To(Equal([]tls.CurveID{19, 20, 21}))
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user