title: How to verify peer certificates in TLS listener
body: <p>I am writing a TLS listener and accepting new connections. The new connections must be verified against a list of SHA1s before continuing. The issue is that <code>tls.Listen()</code> returns a listener of the interface <code>net.Listener</code>. This means <code>Accept()</code> will yield plain-jane <code>net.Conn</code> and not the <code>tls.Conn</code> which provides a <code>ConnectionState().PeerCertificates</code>.</p>
  
  <p>The accepted <code>net.Conn</code> are too basic but when I cast to the more specific <code>*tls.Conn</code> type I receive a runtime exception.</p>
  
  <pre><code>package main
  
  import (
      "crypto/tls"
      "fmt"
      "net"
  )
  
  type Service struct {
      listener net.Listener
  }
  
  func (serv *Service)Listen(port int64) (err error) {
      cert, err := tls.LoadX509KeyPair( "/etc/SCAMP/services/helloworld.crt","/etc/SCAMP/services/helloworld.key" )
      if err != nil {
          return
      }
  
      config := &amp;tls.Config{
          Certificates: []tls.Certificate{ cert },
      }
  
      serv.listener,err = tls.Listen("tcp", "127.0.0.1:30101", config)
      if err != nil {
          return err
      }
  
      return
  }
  
  func (serv *Service)AcceptRequests() {
      for {
          netConn,_ := serv.listener.Accept()
          var tlsConn (*tls.Conn) = netConn.(*tls.Conn)
  
          certs := tlsConn.ConnectionState().PeerCertificates
  
          fmt.Printf("got certs: `%s`\n", certs)
      }
  }
  
  func main() {
      serv := new(Service)
      serv.Listen(30100)
  
      tlsConn, _ := tls.Dial("tcp","127.0.0.1:30101", &amp;tls.Config{
          InsecureSkipVerify: true,
      })
      tlsConn.Write([]byte("hey"))
  }
  </code></pre>
  
  <p>which errors as such:</p>
  
  <pre><code>panic: runtime error: invalid memory address or nil pointer dereference
  [signal 0xb code=0xffffffff addr=0x0 pc=0x78a77]
  
  goroutine 1 [running]:
  crypto/tls.(*Conn).Handshake(0x0, 0x1050a008, 0x0, 0x0)
      /usr/src/go/src/crypto/tls/conn.go:967 +0x317
  crypto/tls.(*Conn).Write(0x0, 0x10538120, 0x3, 0x8, 0x0, 0x0, 0x0, 0xfefd2220)
      /usr/src/go/src/crypto/tls/conn.go:845 +0x80
  main.main()
      /tmp/sandbox290881341/main.go:49 +0x1c0
  
  goroutine 2 [runnable]:
  runtime.forcegchelper()
      /usr/src/go/src/runtime/proc.go:90
  runtime.goexit()
      /usr/src/go/src/runtime/asm_amd64p32.s:1086 +0x1
  
  goroutine 3 [runnable]:
  runtime.bgsweep()
      /usr/src/go/src/runtime/mgc0.go:82
  runtime.goexit()
      /usr/src/go/src/runtime/asm_amd64p32.s:1086 +0x1
  
  goroutine 4 [runnable]:
  runtime.runfinq()
      /usr/src/go/src/runtime/malloc.go:712
  runtime.goexit()
      /usr/src/go/src/runtime/asm_amd64p32.s:1086 +0x1
  </code></pre>
  
  <p><a href="http://play.golang.org/p/gv7dy8XQ81" rel="nofollow">http://play.golang.org/p/gv7dy8XQ81</a></p>