Created
March 29, 2012 01:13
-
Star
(168)
You must be signed in to star a gist -
Fork
(71)
You must be signed in to fork a gist
-
-
Save spikebike/2232102 to your computer and use it in GitHub Desktop.
TLS server and client
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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") | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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") | |
} |
Thank you, it's really help!
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?
In server.go file after the line: log.Print("ok=true"), insert
err = tlscon.Handshake()
if err != nil {
log.Fatalf("Handshake error: %s", err)
}
server.go:17: config.Rand = rand.Reader is not necessary from go1.19 or later at least (and likely not necessary in earlier go versions either). Note that the documentation for tls.Config.Rand says:
If Rand is nil, TLS uses the cryptographic random reader in package crypto/rand.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I think the purpose of this snippet is also to have the server require and verify the client's certificate, which must be configured in the server's TLS config:
ClientAuth: tls.RequireAndVerifyClientCert