ssl - 通过 tls.Server 连接读写

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

我也试过用 Wireshark 嗅探,确实它让我知道我上面说的是什么。此外,调用 Handshake() 显然不是真正的握手。

我做错了什么?

最佳答案

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

关于ssl - 通过 tls.Server 连接读写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23092678/

相关文章:

python - pycurl 和 SSL 证书

io - 使用 io.Copy 响应时,谁应该为错误负责?

c - 在 C 中解析特定格式的文件

java - 使用 java 套接字向多个客户端传输大文件的最佳方法

php - Laravel 5 SSL - 使用过时的密码学加密

security - Kafka SSL 安全设置导致问题

arrays - 在一个 slice 中解码 2 个不同的结构

go - 如何使用 JSON 格式获取 Prometheus 节点导出器指标

c++ - 成功进行 SSL 通信的要求

oop - 是否可以从 Golang 中的父结构调用覆盖的方法?