Skip to content

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

Description

@dzehv

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions