Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
TLS server and client
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(x509.MarshalPKIXPublicKey(v.PublicKey))
fmt.Println(v.Subject)
}
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 joe@random.com
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"
package main
import (
"crypto/rand"
"crypto/tls"
"log"
"net"
"crypto/x509"
)
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}}
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
}
defer conn.Close()
log.Printf("server: accepted from %s", conn.RemoteAddr())
tlscon, ok := conn.(*tls.Conn)
if ok {
log.Print("ok=true")
state := tlscon.ConnectionState()
for _, v := range state.PeerCertificates {
log.Print(x509.MarshalPKIXPublicKey(v.PublicKey))
}
}
go handleClient(conn)
}
}
func handleClient(conn net.Conn) {
defer conn.Close()
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])
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")
}
@btfak

This comment has been minimized.

Copy link

commented Nov 17, 2013

good job!

@jeffkit

This comment has been minimized.

Copy link

commented Dec 25, 2013

great! thank you!

@jvkumar

This comment has been minimized.

Copy link

commented Feb 4, 2014

Thanks for the post. Can you help me to find solution of my TLS config question at http://stackoverflow.com/questions/21562269/golang-how-to-specify-certificate-in-tls-config-for-http-client

@rem7

This comment has been minimized.

Copy link

commented Mar 27, 2014

thanks!

@gosharplite

This comment has been minimized.

Copy link

commented May 7, 2015

You might want to remove line 30 in server.go, it will cause memory leak.

@xtremebeing

This comment has been minimized.

Copy link

commented Dec 4, 2015

I'm using go version go1.5.1 linux/amd64 , the conversion on line 32 of server.go works but tlscon is always empty. Any ideas why?

@itczl22

This comment has been minimized.

Copy link

commented Dec 25, 2016

thanks!

@quiznilo1

This comment has been minimized.

Copy link

commented Nov 16, 2017

What's with line 57 and 59 in the server code?

@mh-cbon

This comment has been minimized.

Copy link

commented May 3, 2018

You might want to remove line 30 in server.go, it will cause memory leak.

to add on this, the defer will not terminate because it is within a for loop. Indeed it is preferable to either undefer the statement, or wrap the for body loop within a func(){}() call.

What's with line 57 and 59 in the server code?

looks likes it is duplicated.

@mimoo

This comment has been minimized.

Copy link

commented Sep 5, 2018

you do not want to have the defer in the loop

@mkrawczuk

This comment has been minimized.

Copy link

commented Sep 5, 2019

In server.go, conn.Close() is called twice - in main() (line 30), and in handleClient() (line 45).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.