golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
124.12k stars 17.68k forks source link

crypto/tls: tls.Dial get error "local error: unexpected message" #7953

Open gopherbot opened 10 years ago

gopherbot commented 10 years ago

by webluoye:

What does 'go version' print?
go version go1.2.1 linux/amd64

What steps reproduce the problem?

If possible, include a link to a program on play.golang.org.
cert, err := tls.LoadX509KeyPair("eeee.crt", "eeee.pem")
if err != nil {
    log.Fatalf("server: loadkeys: %s", err)
}
config := tls.Config{Certificates:
[]tls.Certificate{cert},ClientAuth:tls.VerifyClientCertIfGiven,InsecureSkipVerify: true}
conn, err := tls.Dial("tcp", "218.241.106.8:4121", &config)
if err != nil {
    log.Fatalf("client DialTCP: %s", err)
}

What happened?
tls.Dial get error message "client DialTCP: local error: unexpected message"

What should have happened instead?
it can connect use eeee.pem and eeee.crt via openssl

Please provide any additional information below.
openssl s_client -connect 218.241.106.8:4121 -cert eeee.crt -key eeee.pem -state
-showcerts

---
SSL handshake has read 19310 bytes and written 1018 bytes

---
New, TLSv1/SSLv3, Cipher is EDH-RSA-DES-CBC3-SHA
Server public key is 1024 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : EDH-RSA-DES-CBC3-SHA
    Session-ID: 536B3891C89AACE7E71ACF2D6F3D9D8A723025CD1711863FE075C24F278B7F8D
    Session-ID-ctx: 
    Master-Key: E895BA788756B389744916D6790AD116CF6B669B2242C880791FAF049D9D22183F1750A2CE60BEFA108B79938007B566
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    Start Time: 1399535765
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)

---
<?xml version="1.0" encoding="UTF-8"
standalone="no"?>
ianlancetaylor commented 10 years ago

Comment 1:

Labels changed: added repo-main, release-none.

agl commented 10 years ago

Comment 2:

(Setting ClientAuth on a tls.Config for use in a client doesn't do anything.)
For me, that server doesn't even get to the point of requesting a client certificate:
$ openssl s_client -tls1 -connect 218.241.106.8:4121 -debug
CONNECTED(00000003)
write to 0x113f1f0 [0x1149233] (225 bytes => 225 (0xE1))
0000 - 16 03 01 00 dc 01 00 00-d8 03 01 53 6b f0 d9 31   ...........Sk..1
0010 - 62 df 6b 91 7d 55 83 2f-bd c3 53 39 ea db b8 74   b.k.}U./..S9...t
0020 - e3 df 87 ca 7f 44 fa 2b-36 4e 16 00 00 66 c0 14   .....D.+6N...f..
0030 - c0 0a c0 22 c0 21 00 39-00 38 00 88 00 87 c0 0f   ...".!.9.8......
0040 - c0 05 00 35 00 84 c0 12-c0 08 c0 1c c0 1b 00 16   ...5............
0050 - 00 13 c0 0d c0 03 00 0a-c0 13 c0 09 c0 1f c0 1e   ................
0060 - 00 33 00 32 00 9a 00 99-00 45 00 44 c0 0e c0 04   .3.2.....E.D....
0070 - 00 2f 00 96 00 41 c0 11-c0 07 c0 0c c0 02 00 05   ./...A..........
0080 - 00 04 00 15 00 12 00 09-00 14 00 11 00 08 00 06   ................
0090 - 00 03 00 ff 01 00 00 49-00 0b 00 04 03 00 01 02   .......I........
00a0 - 00 0a 00 34 00 32 00 0e-00 0d 00 19 00 0b 00 0c   ...4.2..........
00b0 - 00 18 00 09 00 0a 00 16-00 17 00 08 00 06 00 07   ................
00c0 - 00 14 00 15 00 04 00 05-00 12 00 13 00 01 00 02   ................
00d0 - 00 03 00 0f 00 10 00 11-00 23 00 00 00 0f 00 01   .........#......
00e0 - 01                                                .
read from 0x113f1f0 [0x1144ce3] (5 bytes => 5 (0x5))
0000 - 15 03 01 00 02                                    .....
read from 0x113f1f0 [0x1144ce8] (2 bytes => 2 (0x2))
0000 - 01                                                .
0002 - <SPACES/NULS>
140649469277856:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake
failure:s3_pkt.c:596:
gopherbot commented 10 years ago

Comment 3 by webluoye:

Thanks all.
but use c language is success.

int main(int argc, char *argv[])
{
        int i,length,buf_len;
        char buf_read[10240];
        char buf_write[10240];
        char domain[100];
        SSL_CTX *ctx;
        SSL *ssl;
        memset(buf_read, '\0', 10240);
        memset(buf_write, '\0', 10240);
        memset(domain, '\0', 100);
        srand((unsigned)time(NULL));

        SSL_load_error_strings();
        SSLeay_add_ssl_algorithms();
        ctx = SSL_CTX_new(SSLv23_client_method());
        CHK_NULL(ctx);
        i = init_ctx(ctx);
        if (0 == i)
        {
                printf("ctx success!\n");
        }
        ssl = SSL_new(ctx);
        CHK_NULL(ssl);
        i = sslConnect(ctx,ssl);
        if (i)
        {
                printf("ssl connect success!\n");
        }
        else
        {
                printf("ssl error!\n");
        }
        i = readFromSSLSocket(ssl,&buf_read,10240,10240);
        if (i > 0)
        {
                printf("size = %d ssl_read:%s\n",i,buf_read);
        }
        else
        {
                printf("SSL_read error!\n");
        }
        ssl_error(ctx,ssl);
        return 0;
}
int init_ctx(SSL_CTX *ctx)
{
        int err;
        char *server_name,*pathname,*client_name,*client_key;
        client_name = "eeee.crt";
        client_key = "eeee.pem";
        err = setClientVerification(ctx);
        CHK_SSL(err);
        err = setCertFile(ctx,client_name,SSL_FILETYPE_PEM);
        CHK_SSL(err);
        err = setPrivateKey(ctx,client_key,SSL_FILETYPE_PEM);
        CHK_SSL(err);
        err = checkPrivateKey(ctx);
        CHK_SSL(err);
        return 0;
}
int sslConnect(SSL_CTX *ctx,SSL *ssl)
{
        int sock,port;
        char *host = "sheep.cnnic.cn";
        port = 4121;
        sock = openSocket(host,port);
        return handShake(ssl,sock);
}
int writeToSSLSocket(SSL *ssl,char *request,int length)
{
        int bytesWritten;
        bytesWritten = SSL_write(ssl,request,length);
        return bytesWritten;
}
---------------------------------------------------------------
the Program result:
ctx success!
ssl connect success!
size = 1199 ssl_read:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:iana:xml:ns:epp-1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:iana:xml:ns:epp-1.0 epp-1.0.xsd">
 <greeting>
  <svID>CNNIC EPP Server</svID>
  <svDate>2014-05-09T01:19:14.0Z</svDate>
  <svcMenu>
   <version>1.0</version>
   <lang>en-US</lang>
   <contact:svc xmlns:contact="urn:iana:xml:ns:contact-1.0" xsi:schemaLocation="urn:iana:xml:ns:contact-1.0 contact-1.0.xsd"/>
   <host:svc xmlns:host="urn:iana:xml:ns:host-1.0" xsi:schemaLocation="urn:iana:xml:ns:host-1.0 host-1.0.xsd"/>
   <domain:svc xmlns:domain="urn:iana:xml:ns:domain-1.0" xsi:schemaLocation="urn:iana:xml:ns:domain-1.0 domain-1.0.xsd"/>
   <unspec>
    <cnContact:svc xmlns:cnContact="urn:iana:xml:ns:cntld:contact-1.0" xsi:schemaLocation="urn:iana:xml:ns:cntld:contact-1.0 cntld-contact-1.0.xsd"/>
    <cnDomain:svc xmlns:cnDomain="urn:iana:xml:ns:cntld:domain-1.0" xsi:schemaLocation="urn:iana:xml:ns:cntld:domain-1.0 cntld-domain-1.0.xsd"/>
    <cnHost:svc xmlns:cnHost="urn:iana:xml:ns:cntld:host-1.0" xsi:schemaLocation="urn:iana:xml:ns:cntld:host-1.0 cntld-host-1.0.xsd"/>
   </unspec>
  </svcMenu>
 </greeting>
</epp>
gopherbot commented 10 years ago

Comment 4 by webluoye:

Connect to sheep.cnnic.cn:4121 needs IP authorization, so you might fail from your end
agl commented 10 years ago

Comment 5:

If I can't test the server then I'll need a tcpdump (i.e. tcpdump -i eth0 -s 9999 -w
/tmp/dump) to see what's going on.
agl commented 10 years ago

Comment 6:

Status changed to WaitingForReply.

gopherbot commented 10 years ago

Comment 7 by webluoye:

commad
tcpdump host 218.241.106.8 -i em1 -s 9999 -w /tmp/dump

Attachments:

  1. dump (7102 bytes)
agl commented 10 years ago

Comment 8:

Wireshark can't decode that because the reply handshake is truncated by the alert from
the client. But the issue is likely because of the huge handshake from the server
(nearly 20KB). The Go code should be handling that, but I can imagine that it might not.
I'll take a look at writing a test for that and seeing if I can shake out a bug.

Owner changed to @agl.

Status changed to Accepted.

gopherbot commented 10 years ago

Comment 9 by webluoye:

use "go version go1.3.1 linux/amd64" 
error info
connection to server sheep.cnnic.cn Handshake false tls: first record does not look like
a TLS handshake
jvehent commented 8 years ago

I'm seeing a problem that looks awfully familiar on https://nakamastreamingcommunity.com.

package main
import (
    "fmt"
    "net/http"
)
func main() {
    fmt.Println(http.Get("https://nakamastreamingcommunity.com"))
}
$ go run get.go 
<nil> Get https://nakamastreamingcommunity.com: local error: unexpected message

Wireshark indicates the Go client cuts the handshake after the SERVER HELLO DONE with the following alert.

Secure Sockets Layer
    TLSv1.2 Record Layer: Alert (Level: Fatal, Description: Unexpected Message)
        Content Type: Alert (21)
        Version: TLS 1.0 (0x0301)
        Length: 2
        Alert Message
            Level: Fatal (2)
            Description: Unexpected Message (10)
woodsaj commented 8 years ago

@jvehent your problem appears to be the same as https://github.com/golang/go/issues/17958

delivey commented 3 years ago

Any updates? Still getting this error when accessing https://www.off---white.com/

EDIT: Nevermind, turns out it was an issue in another TLS library I'm using, not this one.

davecheney commented 3 years ago

@delivey this issue is 7 years old. I recommend that you open a new issue, complete the template, and provide a runnable code sample that someone who is not in your environment can attempt to reproduce the issue you are having.