通过tls.Server连接读取和写入

时间:2014-04-15 19:26:57

标签: ssl io go

我在Go中编写SMTP服务器。实现STARTTLS命令需要使用crypto/tls包。 Here似乎我应该能够"转换" net.Conn对象为tls.Conn,然后我可以使用TLS提供的加密无缝读写。

但是,即使我能够完成上述的第一部分,当我尝试读取或写入受TLS保护的连接时,所调用的Read()和Write()函数也不是tls.Conn对象,但是底层的net.Conn对象。

我目前正在做的事情如下:

type Handler struct {
    Conn net.Conn
}
//...
client := Handler{Conn: /*socket*/}
client.Conn.Write([]byte("Hello!")) //regular write
//the STARTTLS command has been received, switch to tls.Conn and handshake
client.Conn = tls.Server(client.Conn, &TlsConfig) //client.Conn should be now of type tls.Conn
//either casting or not give me the same results
client.Conn.Handshake() //not necessary, it is called on the first Read() or Write() by default
//...
client.Conn.Write([]byte("Hello again!")) //writes clear, unencrypted text
//...
rdr := bufio.NewReader(client.Conn) //might this be the culprit? I don't think it is, since it should just wrap the regular functions
line, err := rdr.ReadString/*or Line*/('\n')
//...
//line = something like À"À!27ÀÀ9ÀÀÀÀ and other client-encrypted text

我已经看到很多人(包括标准net/smtp包)使用text/proto包来解析客户端命令。但是,我想使用我自己的(并且也希望对此进行排序)。正如之前的评论一样,我不认为罪魁祸首在于此,因为它应该只包装函数,不应该吗?

可能是client.Conn = tls.Server(client.Conn, &TlsConfig)对象切换?

我使用的SSL密钥和证书是自签名的,使用OpenSSL生成。 为了测试,我使用了上面链接的StackOverflow问题中建议的两种方法:openssl s_client -starttls smtp -crlf [-tls1] -connect localhost:25和一个简单的net/smtp.SendMail()调用。我正在编译Go 1.2.1(linux / amd64)。

我也试过用Wireshark嗅闻,事实上它让我知道我上面说的话。此外,调用握手()并不显然实际上是握手。

我做错了什么?

1 个答案:

答案 0 :(得分:0)

尝试将TLS连接存储在*tls.Conn类型的新变量中。发起握手并检查ConnectionState()告诉的内容。