Skip to content

Instantly share code, notes, and snippets.

@jim3ma
Forked from spikebike/client.go
Last active June 29, 2023 02:17
Show Gist options
  • Star 32 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save jim3ma/00523f865b8801390475c4e2049fe8c3 to your computer and use it in GitHub Desktop.
Save jim3ma/00523f865b8801390475c4e2049fe8c3 to your computer and use it in GitHub Desktop.
Golang TLS server and client
#!/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/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")
}
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])
log.Printf("server: conn: wrote %d bytes", n)
if err != nil {
log.Printf("server: write: %s", err)
break
}
}
log.Println("server: conn: closed")
}
@rishiba
Copy link

rishiba commented Jan 21, 2019

At line 57 and 59 of tls-server.go why are you writing two times ?

@deefstes
Copy link

I was also wondering why n, err = conn.Write(buf[:n]) is repeated in lines 57 and 59, and why the buffer isn't echoed twice back to the sender. This code compiles and runs fine but despite that repetition, I'm still just getting one response from the server. Why not two?

@acagastya
Copy link

This was a life saver! Now I finally know how to connect to IRC using SSL. Thanks a tonne, @jim3ma.

@jim3ma
Copy link
Author

jim3ma commented Jul 4, 2021

At line 57 and 59 of tls-server.go why are you writing two times ?

Mistake, sorry.

@jim3ma
Copy link
Author

jim3ma commented Jul 4, 2021

I was also wondering why n, err = conn.Write(buf[:n]) is repeated in lines 57 and 59, and why the buffer isn't echoed twice back to the sender. This code compiles and runs fine but despite that repetition, I'm still just getting one response from the server. Why not two?

Mistake, sorry.

@SanDanCrazy
Copy link

hi, I wonder in client config there is 'InsecureSkipVerify: true' pair, if it skips verify, what's the meaning of this test?

@apex-omontgomery
Copy link

hi, I wonder in client config there is 'InsecureSkipVerify: true' pair, if it skips verify, what's the meaning of this test?

This is a way to inform the client that if the server has untrusted certificate chain (or a host of other errors) to not error out. This should only be used for testing / initial development and should NEVER be used in production.

@jim3ma
Copy link
Author

jim3ma commented Jul 29, 2021

hi, I wonder in client config there is 'InsecureSkipVerify: true' pair, if it skips verify, what's the meaning of this test?

When use in production, add CA Pool and disable InsecureSkipVerify.

@Linuxpizi
Copy link

server in lines 30 defer conn.Close(), right ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment