mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 12:47:36 +03:00
expose crypto/tls errors on the TransportError (#4015)
This commit is contained in:
parent
f7f4872bb9
commit
501cc21c4b
8 changed files with 40 additions and 13 deletions
2
go.mod
2
go.mod
|
@ -8,7 +8,7 @@ require (
|
||||||
github.com/onsi/ginkgo/v2 v2.9.5
|
github.com/onsi/ginkgo/v2 v2.9.5
|
||||||
github.com/onsi/gomega v1.27.6
|
github.com/onsi/gomega v1.27.6
|
||||||
github.com/quic-go/qpack v0.4.0
|
github.com/quic-go/qpack v0.4.0
|
||||||
github.com/quic-go/qtls-go1-20 v0.3.1
|
github.com/quic-go/qtls-go1-20 v0.3.2
|
||||||
golang.org/x/crypto v0.4.0
|
golang.org/x/crypto v0.4.0
|
||||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db
|
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db
|
||||||
golang.org/x/net v0.10.0
|
golang.org/x/net v0.10.0
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -90,8 +90,8 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7q
|
||||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||||
github.com/quic-go/qtls-go1-20 v0.3.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg=
|
github.com/quic-go/qtls-go1-20 v0.3.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQq5GI=
|
||||||
github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
github.com/quic-go/qtls-go1-20 v0.3.2/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
||||||
|
|
|
@ -136,8 +136,8 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7q
|
||||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||||
github.com/quic-go/qtls-go1-20 v0.3.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg=
|
github.com/quic-go/qtls-go1-20 v0.3.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQq5GI=
|
||||||
github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
github.com/quic-go/qtls-go1-20 v0.3.2/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
||||||
|
|
|
@ -202,6 +202,8 @@ var _ = Describe("Handshake tests", func() {
|
||||||
Expect(errors.As(err, &transportErr)).To(BeTrue())
|
Expect(errors.As(err, &transportErr)).To(BeTrue())
|
||||||
Expect(transportErr.ErrorCode.IsCryptoError()).To(BeTrue())
|
Expect(transportErr.ErrorCode.IsCryptoError()).To(BeTrue())
|
||||||
Expect(transportErr.Error()).To(ContainSubstring("x509: certificate is valid for localhost, not foo.bar"))
|
Expect(transportErr.Error()).To(ContainSubstring("x509: certificate is valid for localhost, not foo.bar"))
|
||||||
|
var certErr *tls.CertificateVerificationError
|
||||||
|
Expect(errors.As(transportErr, &certErr)).To(BeTrue())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("fails the handshake if the client fails to provide the requested client cert", func() {
|
It("fails the handshake if the client fails to provide the requested client cert", func() {
|
||||||
|
|
|
@ -664,8 +664,9 @@ func (h *cryptoSetup) ConnectionState() ConnectionState {
|
||||||
}
|
}
|
||||||
|
|
||||||
func wrapError(err error) error {
|
func wrapError(err error) error {
|
||||||
|
// alert 80 is an internal error
|
||||||
if alertErr := qtls.AlertError(0); errors.As(err, &alertErr) && alertErr != 80 {
|
if alertErr := qtls.AlertError(0); errors.As(err, &alertErr) && alertErr != 80 {
|
||||||
return qerr.NewLocalCryptoError(uint8(alertErr), err.Error())
|
return qerr.NewLocalCryptoError(uint8(alertErr), err)
|
||||||
}
|
}
|
||||||
return &qerr.TransportError{ErrorCode: qerr.InternalError, ErrorMessage: err.Error()}
|
return &qerr.TransportError{ErrorCode: qerr.InternalError, ErrorMessage: err.Error()}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,15 +17,16 @@ type TransportError struct {
|
||||||
FrameType uint64
|
FrameType uint64
|
||||||
ErrorCode TransportErrorCode
|
ErrorCode TransportErrorCode
|
||||||
ErrorMessage string
|
ErrorMessage string
|
||||||
|
error error // only set for local errors, sometimes
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ error = &TransportError{}
|
var _ error = &TransportError{}
|
||||||
|
|
||||||
// NewLocalCryptoError create a new TransportError instance for a crypto error
|
// NewLocalCryptoError create a new TransportError instance for a crypto error
|
||||||
func NewLocalCryptoError(tlsAlert uint8, errorMessage string) *TransportError {
|
func NewLocalCryptoError(tlsAlert uint8, err error) *TransportError {
|
||||||
return &TransportError{
|
return &TransportError{
|
||||||
ErrorCode: 0x100 + TransportErrorCode(tlsAlert),
|
ErrorCode: 0x100 + TransportErrorCode(tlsAlert),
|
||||||
ErrorMessage: errorMessage,
|
error: err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +36,9 @@ func (e *TransportError) Error() string {
|
||||||
str += fmt.Sprintf(" (frame type: %#x)", e.FrameType)
|
str += fmt.Sprintf(" (frame type: %#x)", e.FrameType)
|
||||||
}
|
}
|
||||||
msg := e.ErrorMessage
|
msg := e.ErrorMessage
|
||||||
|
if len(msg) == 0 && e.error != nil {
|
||||||
|
msg = e.error.Error()
|
||||||
|
}
|
||||||
if len(msg) == 0 {
|
if len(msg) == 0 {
|
||||||
msg = e.ErrorCode.Message()
|
msg = e.ErrorCode.Message()
|
||||||
}
|
}
|
||||||
|
@ -48,6 +52,10 @@ func (e *TransportError) Is(target error) bool {
|
||||||
return target == net.ErrClosed
|
return target == net.ErrClosed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *TransportError) Unwrap() error {
|
||||||
|
return e.error
|
||||||
|
}
|
||||||
|
|
||||||
// An ApplicationErrorCode is an application-defined error code.
|
// An ApplicationErrorCode is an application-defined error code.
|
||||||
type ApplicationErrorCode uint64
|
type ApplicationErrorCode uint64
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package qerr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/quic-go/quic-go/internal/protocol"
|
"github.com/quic-go/quic-go/internal/protocol"
|
||||||
|
@ -10,6 +11,12 @@ import (
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type myError int
|
||||||
|
|
||||||
|
var _ error = myError(0)
|
||||||
|
|
||||||
|
func (e myError) Error() string { return fmt.Sprintf("my error %d", e) }
|
||||||
|
|
||||||
var _ = Describe("QUIC Errors", func() {
|
var _ = Describe("QUIC Errors", func() {
|
||||||
Context("Transport Errors", func() {
|
Context("Transport Errors", func() {
|
||||||
It("has a string representation", func() {
|
It("has a string representation", func() {
|
||||||
|
@ -41,12 +48,20 @@ var _ = Describe("QUIC Errors", func() {
|
||||||
|
|
||||||
Context("crypto errors", func() {
|
Context("crypto errors", func() {
|
||||||
It("has a string representation for errors with a message", func() {
|
It("has a string representation for errors with a message", func() {
|
||||||
err := NewLocalCryptoError(0x42, "foobar")
|
myErr := myError(1337)
|
||||||
Expect(err.Error()).To(Equal("CRYPTO_ERROR 0x142 (local): foobar"))
|
err := NewLocalCryptoError(0x42, myErr)
|
||||||
|
Expect(err.Error()).To(Equal("CRYPTO_ERROR 0x142 (local): my error 1337"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("unwraps errors", func() {
|
||||||
|
var myErr myError
|
||||||
|
err := NewLocalCryptoError(0x42, myError(1337))
|
||||||
|
Expect(errors.As(err, &myErr)).To(BeTrue())
|
||||||
|
Expect(myErr).To(BeEquivalentTo(1337))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("has a string representation for errors without a message", func() {
|
It("has a string representation for errors without a message", func() {
|
||||||
err := NewLocalCryptoError(0x2a, "")
|
err := NewLocalCryptoError(0x2a, nil)
|
||||||
Expect(err.Error()).To(Equal("CRYPTO_ERROR 0x12a (local): tls: bad certificate"))
|
Expect(err.Error()).To(Equal("CRYPTO_ERROR 0x12a (local): tls: bad certificate"))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,6 +2,7 @@ package quic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
@ -334,7 +335,7 @@ var _ = Describe("Packet packer", func() {
|
||||||
sealingManager.EXPECT().GetInitialSealer().Return(nil, handshake.ErrKeysDropped)
|
sealingManager.EXPECT().GetInitialSealer().Return(nil, handshake.ErrKeysDropped)
|
||||||
sealingManager.EXPECT().GetHandshakeSealer().Return(getSealer(), nil)
|
sealingManager.EXPECT().GetHandshakeSealer().Return(getSealer(), nil)
|
||||||
sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable)
|
||||||
quicErr := qerr.NewLocalCryptoError(0x42, "crypto error")
|
quicErr := qerr.NewLocalCryptoError(0x42, errors.New("crypto error"))
|
||||||
quicErr.FrameType = 0x1234
|
quicErr.FrameType = 0x1234
|
||||||
p, err := packer.PackConnectionClose(quicErr, maxPacketSize, protocol.Version1)
|
p, err := packer.PackConnectionClose(quicErr, maxPacketSize, protocol.Version1)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue