forked from quic-go/quic-go
return the local TLS error, but don't send it on the wire
This commit is contained in:
@@ -138,8 +138,7 @@ var _ = Describe("Handshake tests", func() {
|
|||||||
tlsConf,
|
tlsConf,
|
||||||
clientConfig,
|
clientConfig,
|
||||||
)
|
)
|
||||||
// TODO: check the error returned locally here
|
Expect(err).To(MatchError("CRYPTO_ERROR: x509: cannot validate certificate for 127.0.0.1 because it doesn't contain any IP SANs"))
|
||||||
Expect(err).To(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
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() {
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ type cryptoSetup struct {
|
|||||||
|
|
||||||
handleParamsCallback func([]byte)
|
handleParamsCallback func([]byte)
|
||||||
|
|
||||||
alertChan chan error
|
alertChan chan uint8
|
||||||
// HandleData() sends errors on the messageErrChan
|
// HandleData() sends errors on the messageErrChan
|
||||||
messageErrChan chan error
|
messageErrChan chan error
|
||||||
// handshakeDone is closed as soon as the go routine running qtls.Handshake() returns
|
// handshakeDone is closed as soon as the go routine running qtls.Handshake() returns
|
||||||
@@ -187,7 +187,7 @@ func newCryptoSetup(
|
|||||||
logger: logger,
|
logger: logger,
|
||||||
perspective: perspective,
|
perspective: perspective,
|
||||||
handshakeDone: make(chan struct{}),
|
handshakeDone: make(chan struct{}),
|
||||||
alertChan: make(chan error),
|
alertChan: make(chan uint8),
|
||||||
messageErrChan: make(chan error, 1),
|
messageErrChan: make(chan error, 1),
|
||||||
clientHelloWrittenChan: make(chan struct{}),
|
clientHelloWrittenChan: make(chan struct{}),
|
||||||
messageChan: make(chan []byte, 100),
|
messageChan: make(chan []byte, 100),
|
||||||
@@ -213,10 +213,11 @@ func (h *cryptoSetup) ChangeConnectionID(id protocol.ConnectionID) error {
|
|||||||
func (h *cryptoSetup) RunHandshake() error {
|
func (h *cryptoSetup) RunHandshake() error {
|
||||||
// Handle errors that might occur when HandleData() is called.
|
// Handle errors that might occur when HandleData() is called.
|
||||||
handshakeComplete := make(chan struct{})
|
handshakeComplete := make(chan struct{})
|
||||||
|
handshakeErrChan := make(chan error, 1)
|
||||||
go func() {
|
go func() {
|
||||||
defer close(h.handshakeDone)
|
defer close(h.handshakeDone)
|
||||||
if err := h.conn.Handshake(); err != nil {
|
if err := h.conn.Handshake(); err != nil {
|
||||||
h.logger.Debugf("qlts.Handshake error: %s", err)
|
handshakeErrChan <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
close(handshakeComplete)
|
close(handshakeComplete)
|
||||||
@@ -229,9 +230,9 @@ func (h *cryptoSetup) RunHandshake() error {
|
|||||||
return errors.New("Handshake aborted")
|
return errors.New("Handshake aborted")
|
||||||
case <-handshakeComplete: // return when the handshake is done
|
case <-handshakeComplete: // return when the handshake is done
|
||||||
return nil
|
return nil
|
||||||
case err := <-h.alertChan:
|
case alert := <-h.alertChan:
|
||||||
<-h.handshakeDone
|
err := <-handshakeErrChan
|
||||||
return err
|
return qerr.CryptoError(alert, err.Error())
|
||||||
case err := <-h.messageErrChan:
|
case err := <-h.messageErrChan:
|
||||||
// If the handshake errored because of an error that occurred during HandleData(),
|
// If the handshake errored because of an error that occurred during HandleData(),
|
||||||
// that error message will be more useful than the error message generated by Handshake().
|
// that error message will be more useful than the error message generated by Handshake().
|
||||||
@@ -462,7 +463,7 @@ func (h *cryptoSetup) WriteRecord(p []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *cryptoSetup) SendAlert(alert uint8) {
|
func (h *cryptoSetup) SendAlert(alert uint8) {
|
||||||
h.alertChan <- qerr.CryptoError(alert, "")
|
h.alertChan <- alert
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *cryptoSetup) GetSealer() (protocol.EncryptionLevel, Sealer) {
|
func (h *cryptoSetup) GetSealer() (protocol.EncryptionLevel, Sealer) {
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ var _ = Describe("Crypto Setup TLS", func() {
|
|||||||
go func() {
|
go func() {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
err := server.RunHandshake()
|
err := server.RunHandshake()
|
||||||
Expect(err).To(MatchError("CRYPTO_ERROR: tls: unexpected message"))
|
Expect(err).To(MatchError("CRYPTO_ERROR: local error: tls: unexpected message"))
|
||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ func (e *QuicError) Error() string {
|
|||||||
return fmt.Sprintf("%s: %s", e.ErrorCode.String(), e.ErrorMessage)
|
return fmt.Sprintf("%s: %s", e.ErrorCode.String(), e.ErrorMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsCryptoError says if this error is a crypto error
|
||||||
|
func (e *QuicError) IsCryptoError() bool {
|
||||||
|
return e.ErrorCode.isCryptoError()
|
||||||
|
}
|
||||||
|
|
||||||
// Temporary says if the error is temporary.
|
// Temporary says if the error is temporary.
|
||||||
func (e *QuicError) Temporary() bool {
|
func (e *QuicError) Temporary() bool {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -25,14 +25,21 @@ var _ = Describe("QUIC Transport Errors", func() {
|
|||||||
Expect(err.Error()).To(Equal("NO_ERROR: foobar"))
|
Expect(err.Error()).To(Equal("NO_ERROR: foobar"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("has a string representation for crypto errors with a message", func() {
|
Context("crypto errors", func() {
|
||||||
err := CryptoError(42, "foobar")
|
It("has a string representation for crypto errors with a message", func() {
|
||||||
Expect(err.Error()).To(Equal("CRYPTO_ERROR: foobar"))
|
err := CryptoError(42, "foobar")
|
||||||
})
|
Expect(err.Error()).To(Equal("CRYPTO_ERROR: foobar"))
|
||||||
|
})
|
||||||
|
|
||||||
It("has a string representation for crypto errors without a message", func() {
|
It("has a string representation for crypto errors without a message", func() {
|
||||||
err := CryptoError(42, "")
|
err := CryptoError(42, "")
|
||||||
Expect(err.Error()).To(Equal("CRYPTO_ERROR: tls: bad certificate"))
|
Expect(err.Error()).To(Equal("CRYPTO_ERROR: tls: bad certificate"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("says if an error is a crypto error", func() {
|
||||||
|
Expect(Error(FlowControlError, "").IsCryptoError()).To(BeFalse())
|
||||||
|
Expect(CryptoError(42, "").IsCryptoError()).To(BeTrue())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("ErrorCode", func() {
|
Context("ErrorCode", func() {
|
||||||
|
|||||||
@@ -1133,9 +1133,14 @@ func (s *session) sendPackedPacket(packet *packedPacket) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *session) sendConnectionClose(quicErr *qerr.QuicError) error {
|
func (s *session) sendConnectionClose(quicErr *qerr.QuicError) error {
|
||||||
|
var reason string
|
||||||
|
// don't send details of crypto errors
|
||||||
|
if !quicErr.IsCryptoError() {
|
||||||
|
reason = quicErr.ErrorMessage
|
||||||
|
}
|
||||||
packet, err := s.packer.PackConnectionClose(&wire.ConnectionCloseFrame{
|
packet, err := s.packer.PackConnectionClose(&wire.ConnectionCloseFrame{
|
||||||
ErrorCode: quicErr.ErrorCode,
|
ErrorCode: quicErr.ErrorCode,
|
||||||
ReasonPhrase: quicErr.ErrorMessage,
|
ReasonPhrase: reason,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
Reference in New Issue
Block a user