Go has wonderful support for server side TLS, but the client side takes a little bit of massaging to generate a correct Config struct. Check out this thread from Hans Stimer for more details on handling TLS on the server side.
package main
import (
"crypto/tls"
"io/ioutil"
"net"
"os"
"time"
)
func loadRootCA(file string) (*tls.CASet, os.Error) {
pemBytes, err := ioutil.ReadFile(file)
if err != nil {
return nil, err
}
caset := tls.NewCASet()
if caset.SetFromPEM(pemBytes) {
return caset, nil
}
return nil, os.NewError("Unable to decode root CA set")
}
func newClientConfig(rootCAPath string) (*tls.Config, os.Error) {
rootca, err := loadRootCA(rootCAPath)
if err != nil {
return nil, err
}
urandom, err := os.Open("/dev/urandom", os.O_RDONLY, 0)
if err != nil {
return nil, err
}
return &tls.Config{
Rand: urandom,
Time: time.Seconds,
RootCAs: rootca,
}, nil
}
func dialTLS(raddr *net.TCPAddr) (c *tls.Conn, err os.Error) {
config, err := newClientConfig("ca-certificates.crt")
if err != nil {
return nil, err
}
conn, err := net.DialTCP("tcp", nil, raddr)
if err != nil {
return nil, err
}
c = tls.Client(conn, config)
err = c.Handshake()
if err == nil {
return c, nil
}
c.Close()
return nil, err
}