diff --git a/integrationtests/self/handshake_test.go b/integrationtests/self/handshake_test.go index c6dbbfc6..741b6f31 100644 --- a/integrationtests/self/handshake_test.go +++ b/integrationtests/self/handshake_test.go @@ -24,12 +24,14 @@ var _ = Describe("Handshake tests", func() { server quic.Listener serverConfig *quic.Config acceptStopped chan struct{} + tlsServerConf *tls.Config ) BeforeEach(func() { server = nil acceptStopped = make(chan struct{}) serverConfig = &quic.Config{} + tlsServerConf = testdata.GetTLSConfig() }) AfterEach(func() { @@ -42,7 +44,7 @@ var _ = Describe("Handshake tests", func() { runServer := func() quic.Listener { var err error // start the server - server, err = quic.ListenAddr("localhost:0", testdata.GetTLSConfig(), serverConfig) + server, err = quic.ListenAddr("localhost:0", tlsServerConf, serverConfig) Expect(err).ToNot(HaveOccurred()) go func() { @@ -117,8 +119,11 @@ var _ = Describe("Handshake tests", func() { } }) - It("accepts the certificate", func() { + JustBeforeEach(func() { runServer() + }) + + It("accepts the certificate", func() { _, err := quic.DialAddr( fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), tlsConf, @@ -128,17 +133,34 @@ var _ = Describe("Handshake tests", func() { }) It("errors if the server name doesn't match", func() { - runServer() _, err := quic.DialAddr( fmt.Sprintf("127.0.0.1:%d", server.Addr().(*net.UDPAddr).Port), tlsConf, clientConfig, ) + // TODO: check the error returned locally here Expect(err).To(HaveOccurred()) }) + It("fails the handshake if the client fails to provide the requested client cert", func() { + tlsServerConf.ClientAuth = tls.RequireAndVerifyClientCert + sess, err := quic.DialAddr( + fmt.Sprintf("localhost:%d", server.Addr().(*net.UDPAddr).Port), + tlsConf, + clientConfig, + ) + Expect(err).ToNot(HaveOccurred()) + // The error will occur after the client already finished the handshake. + errChan := make(chan error) + go func() { + defer GinkgoRecover() + _, err := sess.AcceptStream() + errChan <- err + }() + Eventually(errChan).Should(Receive(MatchError("CRYPTO_ERROR: tls: bad certificate"))) + }) + It("uses the ServerName in the tls.Config", func() { - runServer() tlsConf.ServerName = "localhost" _, err := quic.DialAddr( fmt.Sprintf("127.0.0.1:%d", server.Addr().(*net.UDPAddr).Port), diff --git a/internal/handshake/crypto_setup.go b/internal/handshake/crypto_setup.go index 5015164a..2c90089e 100644 --- a/internal/handshake/crypto_setup.go +++ b/internal/handshake/crypto_setup.go @@ -8,6 +8,7 @@ import ( "io" "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/qerr" "github.com/lucas-clemente/quic-go/internal/utils" "github.com/marten-seemann/qtls" ) @@ -461,8 +462,7 @@ func (h *cryptoSetup) WriteRecord(p []byte) (int, error) { } func (h *cryptoSetup) SendAlert(alert uint8) { - // TODO(#1804): send the correct IETF QUIC error code - h.alertChan <- fmt.Errorf("TLS alert: %d", alert) + h.alertChan <- qerr.CryptoError(alert) } func (h *cryptoSetup) GetSealer() (protocol.EncryptionLevel, Sealer) { diff --git a/internal/handshake/crypto_setup_test.go b/internal/handshake/crypto_setup_test.go index c2390fd6..cd541a68 100644 --- a/internal/handshake/crypto_setup_test.go +++ b/internal/handshake/crypto_setup_test.go @@ -128,7 +128,7 @@ var _ = Describe("Crypto Setup TLS", func() { go func() { defer GinkgoRecover() err := server.RunHandshake() - Expect(err).To(MatchError("TLS alert: 10")) + Expect(err).To(MatchError("CRYPTO_ERROR: tls: unexpected message")) close(done) }()