Skip to content

Instantly share code, notes, and snippets.

@kortschak
Created February 20, 2012 00:45
Show Gist options
  • Save kortschak/1866829 to your computer and use it in GitHub Desktop.
Save kortschak/1866829 to your computer and use it in GitHub Desktop.
Example PeerCertificates empty
package main
import (
"bufio"
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"io/ioutil"
"math/big"
"net/http"
"time"
)
const keylen = 1024
var random = rand.Reader
func certificate(name string) (certName, keyName string) {
priv, err := rsa.GenerateKey(random, keylen)
if err != nil {
panic(err)
}
template := x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{
CommonName: name,
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(1, 0, 0),
}
derBytes, err := x509.CreateCertificate(random, &template, &template, &priv.PublicKey, priv)
if err != nil {
panic(err)
}
keyFile, err := ioutil.TempFile("", "")
if err != nil {
panic(err)
}
keyBlock := &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(priv),
}
err = pem.Encode(keyFile, keyBlock)
if err != nil {
panic(err)
}
certFile, err := ioutil.TempFile("", "")
if err != nil {
panic(err)
}
certBlock := &pem.Block{
Type: "CERTIFICATE",
Bytes: derBytes,
}
err = pem.Encode(certFile, certBlock)
if err != nil {
panic(err)
}
return certFile.Name(), keyFile.Name()
}
func httpclient() {
certFile, keyFile := certificate("client")
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
panic(err)
}
config := &tls.Config{
Certificates: []tls.Certificate{cert},
InsecureSkipVerify: true,
}
config.BuildNameToCertificate()
tr := &http.Transport{
TLSClientConfig: config,
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://localhost:10000")
if err != nil {
panic(err)
}
text, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Println(string(text))
}
func handler(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte("This is an example http server.\n"))
fmt.Printf("%#v\n", req.TLS)
if cs := req.TLS; len(cs.PeerCertificates) != 0 {
fmt.Printf("Subject: %#v\n", cs.PeerCertificates[0].Subject.CommonName)
} else {
fmt.Printf("Subject: not available\n")
}
}
func httpserver() {
certFile, keyFile := certificate("server")
http.HandleFunc("/", handler)
err := http.ListenAndServeTLS(":10000", certFile, keyFile, nil)
if err != nil {
panic(err)
}
}
func rawclient() {
certFile, keyFile := certificate("client")
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
panic(err)
}
config := &tls.Config{
Certificates: []tls.Certificate{cert},
ClientAuth: tls.RequireAnyClientCert,
InsecureSkipVerify: true,
}
config.BuildNameToCertificate()
conn, err := tls.Dial("tcp", "localhost:9001", config)
if err != nil {
panic(err)
}
defer conn.Close()
conn.Write([]byte("Hello\n"))
r := bufio.NewReader(conn)
b, err := r.ReadBytes('\n')
if err != nil {
panic(err)
}
fmt.Println(string(b))
}
func rawserver() {
certFile, keyFile := certificate("server")
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
panic(err)
}
config := &tls.Config{
Certificates: []tls.Certificate{cert},
ClientAuth: tls.RequireAnyClientCert,
}
config.BuildNameToCertificate()
listener, err := tls.Listen("tcp", "localhost:9001", config)
if err != nil {
panic(err)
}
defer listener.Close()
conn, err := listener.Accept()
if err != nil {
panic(err)
}
defer conn.Close()
fmt.Printf("Before read: %#v\n", conn.(*tls.Conn).ConnectionState()) // no cert
if cs := conn.(*tls.Conn).ConnectionState(); len(cs.PeerCertificates) != 0 {
fmt.Printf("Subject: %#v\n", cs.PeerCertificates[0].Subject.CommonName)
} else {
fmt.Printf("Subject: not available\n")
}
r := bufio.NewReader(conn) // calls (*tls.Conn.Handshake()
r.ReadBytes('\n')
fmt.Printf("After read: %#v\n", conn.(*tls.Conn).ConnectionState()) // cert exists
if cs := conn.(*tls.Conn).ConnectionState(); len(cs.PeerCertificates) != 0 {
fmt.Printf("Subject: %#v\n", cs.PeerCertificates[0].Subject.CommonName)
} else {
fmt.Printf("Subject: not available\n")
}
conn.Write([]byte("This is an example raw tls server.\n"))
}
func main() {
go httpserver()
go rawserver()
fmt.Println("http")
httpclient()
fmt.Println("raw tls connection")
rawclient()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment