I have an open TCP connection and read from it with a for loop like so
for {
// tx.Text is of type textproto.Conn
// the underlying connection is stored
Here's how to upgrade a net.conn to tls.con:
1) Somewhere in your code, you have these variables defined
var TLSconfig *tls.Config
...
// conn is a normal connection of type net.Conn
conn, err := listener.Accept()
...
2) Initialize TLSConfig somewhere above, do something like this
cert, err := tls.LoadX509KeyPair("/path/to/cert", "/path/to/key")
if err != nil {
// ...
}
TLSconfig = &tls.Config{
Certificates: []tls.Certificate{cert},
ClientAuth: tls.VerifyClientCertIfGiven,
ServerName: "example.com"}
3) At this point you are reading/writing to a standard connection.
When the client issues STARTTLS command, do this in your server:
// Init a new TLS connection. I need a *tls.Conn type
// so that I can do the Handshake()
var tlsConn *tls.Conn
tlsConn = tls.Server(client.socket, TLSconfig)
// run a handshake
tlsConn.Handshake()
// Here is the trick. Since I do not need to access
// any of the TLS functions anymore,
// I can convert tlsConn back in to a net.Conn type
conn = net.Conn(tlsConn)
Next, you may probably update your buffers with the new connection, etc.
Test your server like this:
openssl s_client -starttls smtp -crlf -connect example.com:25
This allows you to interact with the server through the tls connection and you can issue some commands, etc.
I guess conversions are another reason for what makes Go so powerful!
http://golang.org/ref/spec#Conversions
http://golang.org/doc/effective_go.html#conversions