Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto/tls: remote error: tls: handshake failure #46270

Closed
dzehv opened this issue May 19, 2021 · 2 comments
Closed

crypto/tls: remote error: tls: handshake failure #46270

dzehv opened this issue May 19, 2021 · 2 comments

Comments

@dzehv
Copy link

dzehv commented May 19, 2021

This issue can be similar to https://github.com/golang/go/issues/9446, but that one was closed in time, and recipes didn't help.

### What version of Go are you using (go version)?

go version go1.16.3 darwin/amd64

but reproducing also on linux:

go version go1.16 linux/amd64

### Does this issue reproduce with the latest release?
Yes

### What operating system and processor architecture are you using (go env)?

go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/dzehv/Library/Caches/go-build"
GOENV="/Users/dzehv/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/dzehv/gocode/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/dzehv/gocode"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/opt/go/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/opt/go/libexec/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.16.3"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/th/wlk6yc_14yddwsg85jltxnc80000gn/T/go-build1880165201=/tmp/go-build -gno-record-gcc-switches -fno-common"

### What did you do

There were similar topics few years ago, but no solutions worked for my case. I took one of debug examples from that topic https://github.com/golang/go/issues/9446 to demostrate reproducing error:

package main

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"net"
	"os"
	"time"
)

func resolve(u string) {
	dialer := &net.Dialer{
		Timeout: 60 * time.Second,
	}
	rawConn, err := dialer.Dial("tcp", u)
	if err != nil {
		fmt.Println("failed to dial: ", err.Error())
		return
	}
	config := &tls.Config{
		InsecureSkipVerify: true,
		KeyLogWriter:       os.Stdout,
		VerifyConnection: func(cs tls.ConnectionState) error {
			opts := x509.VerifyOptions{
				DNSName:       cs.ServerName,
				Intermediates: x509.NewCertPool(),
				KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
			}
			for _, cert := range cs.PeerCertificates[1:] {
				opts.Intermediates.AddCert(cert)
			}
			_, err := cs.PeerCertificates[0].Verify(opts)
			return err
		},
	}
	conn := tls.Client(rawConn, config)
	fmt.Println(u, conn.Handshake())
	conn.Close()
}

func main() {
	failingUrls := []string{
		"epp.nic.fr:700",
	}
	for _, u := range failingUrls {
		resolve(u)
	}
}

### What did you expect to see?

Handshake was done, like using openssl cli, which is working properly:

openssl s_client -connect epp.nic.fr:700

Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1
Shared Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224
Peer signing digest: SHA256
Peer signature type: RSA
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 18947 bytes and written 440 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: C2360698EDC3E732D42110B6178614C226CA5DA5F692F8FC4D157F1C94EF3BCF2A05BB642D84E739769CE5E957BABC7C
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1621445578
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
---

### What did you see instead?

CLIENT_RANDOM e84c46303892b2073e4cb09cf63f99541bacaf21ccd173a454ef737fcd4412e0 0a60ebce23a314a459867985a00cc35cd6b148f12762e41e07fb818a1f8e6f91262a0c51a6e5e411e183dee577facf51

epp.nic.fr:700 remote error: tls: handshake failure

NOTE: using certs gives the same result, but openssl works properly.

How can I additionaly debug this case to see more information from crypto/tls or server output? There were also more playarounds with tls.Config, cipher suites, etc. Nothing helps for now.

@dzehv dzehv changed the title remote error: tls: handshake failure crypto/tls: remote error: tls: handshake failure May 19, 2021
@ZekeLu
Copy link
Contributor

ZekeLu commented May 20, 2021

In fact, openssl reports an error too:

$ openssl s_client -connect epp.nic.fr:700
CONNECTED(00000003)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = RapidSSL RSA CA 2018
verify return:1
depth=0 CN = *.nic.fr
verify return:1
139815768130880:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:../ssl/record/rec_layer_s3.c:1543:SSL alert number 40
...

curl reports the same error:

$ curl -v https://epp.nic.fr:700
*   Trying 192.134.5.10:700...
* TCP_NODELAY set
*   Trying 2001:67c:2218:e::51:41:700...
* TCP_NODELAY set
* Connected to epp.nic.fr (192.134.5.10) port 700 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS alert, handshake failure (552):
* error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
* Closing connection 0
curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure

The output of openssl has an Acceptable client certificate CA names section. Maybe mTLS is enabled on the server, and the client need to provide a valid cert signed by the listed CA.

@seankhliao
Copy link
Member

Closing for the same reason as #9446 the protocol doesn't provide extra information on why it is a failure

Unlike many projects, the Go project does not use GitHub Issues for general discussion or asking questions. GitHub Issues are used for tracking bugs and proposals only.

For questions please refer to https://github.com/golang/go/wiki/Questions

@golang golang locked and limited conversation to collaborators May 20, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants