Upgrade a connection to TLS in Go

后端 未结 2 1218
不思量自难忘°
不思量自难忘° 2020-12-09 06:51

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          


        
相关标签:
2条回答
  • 2020-12-09 06:51

    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.

    More about conversions in Go

    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

    0 讨论(0)
  • 2020-12-09 07:13

    Ditched swaks, built a small tool to test TLS using Go's own smtp.SendMail:

    package main
    
    import (
      "fmt"
      "net/smtp"
    )
    
    func main() {
      err := smtp.SendMail(
        "127.0.0.1:2525",
        nil,
        "src@test.local",
        []string{"dst@test.local"},
        []byte("Hello! Just testing."),
      )
      if err != nil {
        panic(err)
      }
    }
    
    0 讨论(0)
提交回复
热议问题