Skip to content

Instantly share code, notes, and snippets.

@spikebike
Forked from spikebike/client.go
Created March 29, 2012 03:43
Show Gist options
  • Save spikebike/2233075 to your computer and use it in GitHub Desktop.
Save spikebike/2233075 to your computer and use it in GitHub Desktop.
TLS server and client
$ go run client.go
2012/03/28 22:30:21 client: connected to: 127.0.0.1:8000
Client: Server public key is:
[48 129 159 48 13 6 9 42 134 72 134 247 13 1 1 1 5 0 3 129 141 0 48 129 137 2 129 129 0 188 73 207 11 137 150 106 118 45 27 12 18 76 183 252 31 22 193 109 43 118 130 188 244 197 136 26 55 239 51 225 67 171 20 87 35 107 190 16 158 181 84 225 159 112 70 131 173 136 181 130 151 156 4 142 141 218 100 116 219 228 211 136 155 179 220 50 21 181 134 211 72 22 38 226 51 170 165 39 65 231 3 15 26 54 193 142 242 28 66 96 88 138 237 217 65 144 89 231 177 179 200 116 30 45 148 174 56 57 244 29 17 8 22 86 54 215 14 207 55 223 164 216 184 21 46 29 233 2 3 1 0 1] <nil>
2012/03/28 22:30:21 client: handshake: true
2012/03/28 22:30:21 client: mutual: true
2012/03/28 22:30:21 client: wrote "Hello\n" (6 bytes)
2012/03/28 22:30:21 client: read "Hello\n" (6 bytes)
2012/03/28 22:30:21 client: exiting
$
package main
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io"
"log"
)
func main() {
cert, err := tls.LoadX509KeyPair("certs/client.pem", "certs/client.key")
if err != nil {
log.Fatalf("server: loadkeys: %s", err)
}
config := tls.Config{Certificates: []tls.Certificate{cert}, InsecureSkipVerify: true}
conn, err := tls.Dial("tcp", "127.0.0.1:8000", &config)
if err != nil {
log.Fatalf("client: dial: %s", err)
}
defer conn.Close()
log.Println("client: connected to: ", conn.RemoteAddr())
state := conn.ConnectionState()
for _, v := range state.PeerCertificates {
fmt.Println("Client: Server public key is:")
fmt.Println(x509.MarshalPKIXPublicKey(v.PublicKey))
}
log.Println("client: handshake: ", state.HandshakeComplete)
log.Println("client: mutual: ", state.NegotiatedProtocolIsMutual)
message := "Hello\n"
n, err := io.WriteString(conn, message)
if err != nil {
log.Fatalf("client: write: %s", err)
}
log.Printf("client: wrote %q (%d bytes)", message, n)
reply := make([]byte, 256)
n, err = conn.Read(reply)
log.Printf("client: read %q (%d bytes)", string(reply[:n]), n)
log.Print("client: exiting")
}
#!/bin/bash
# call this script with an email address (valid or not).
# like:
# ./makecert.sh [email protected]
mkdir certs
rm certs/*
echo "make server cert"
openssl req -new -nodes -x509 -out certs/server.pem -keyout certs/server.key -days 3650 -subj "/C=DE/ST=NRW/L=Earth/O=Random Company/OU=IT/CN=www.random.com/emailAddress=$1"
echo "make client cert"
openssl req -new -nodes -x509 -out certs/client.pem -keyout certs/client.key -days 3650 -subj "/C=DE/ST=NRW/L=Earth/O=Random Company/OU=IT/CN=www.random.com/emailAddress=$1"
$ go run server.go
2012/03/28 22:30:17 server: listening
2012/03/28 22:30:21 server: accepted from 127.0.0.1:38020
2012/03/28 22:30:21 server: conn: type assert to TLS succeedded
2012/03/28 22:30:21 server: conn: Handshake completed
2012/03/28 22:30:21 Server: client public key is:
2012/03/28 22:30:21 [48 129 159 48 13 6 9 42 134 72 134 247 13 1 1 1 5 0 3 129 141 0 48 129 137 2 129 129 0 204 185 196 229 49 15 70 253 60 159 47 189 29 191 186 227 79 255 65 205 234 251 13 21 2 185 57 145 54 67 148 140 183 135 146 159 86 19 214 193 143 173 197 143 14 129 165 79 164 255 170 208 21 79 148 6 211 115 54 18 244 61 136 231 86 157 84 192 125 62 56 210 150 103 110 8 95 241 167 39 67 119 95 64 135 60 74 62 184 20 100 162 81 180 177 124 39 236 140 133 137 215 246 184 244 244 74 120 1 18 196 153 228 235 208 173 53 247 148 41 5 166 68 133 160 153 152 231 2 3 1 0 1] <nil>
2012/03/28 22:30:21 server: conn: waiting
2012/03/28 22:30:21 server: conn: echo "Hello\n"
2012/03/28 22:30:21 server: conn: wrote 6 bytes
2012/03/28 22:30:21 server: conn: waiting
2012/03/28 22:30:21 server: conn: read: EOF
2012/03/28 22:30:21 server: conn: closed
package main
import (
"crypto/rand"
"crypto/tls"
"crypto/x509"
"log"
"net"
)
func main() {
cert, err := tls.LoadX509KeyPair("certs/server.pem", "certs/server.key")
if err != nil {
log.Fatalf("server: loadkeys: %s", err)
}
config := tls.Config{Certificates: []tls.Certificate{cert}, ClientAuth: tls.RequireAnyClientCert}
config.Rand = rand.Reader
service := "0.0.0.0:8000"
listener, err := tls.Listen("tcp", service, &config)
if err != nil {
log.Fatalf("server: listen: %s", err)
}
log.Print("server: listening")
for {
conn, err := listener.Accept()
if err != nil {
log.Printf("server: accept: %s", err)
break
}
log.Printf("server: accepted from %s", conn.RemoteAddr())
go handleClient(conn)
}
}
func handleClient(conn net.Conn) {
defer conn.Close()
tlscon, ok := conn.(*tls.Conn)
if ok {
log.Print("server: conn: type assert to TLS succeedded")
err := tlscon.Handshake()
if err != nil {
log.Fatalf("server: handshake failed: %s", err)
} else {
log.Print("server: conn: Handshake completed")
}
state := tlscon.ConnectionState()
log.Println("Server: client public key is:")
for _, v := range state.PeerCertificates {
log.Print(x509.MarshalPKIXPublicKey(v.PublicKey))
}
buf := make([]byte, 512)
for {
log.Print("server: conn: waiting")
n, err := conn.Read(buf)
if err != nil {
if err != nil {
log.Printf("server: conn: read: %s", err)
}
break
}
log.Printf("server: conn: echo %q\n", string(buf[:n]))
n, err = conn.Write(buf[:n])
log.Printf("server: conn: wrote %d bytes", n)
if err != nil {
log.Printf("server: write: %s", err)
break
}
}
}
log.Println("server: conn: closed")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment