This commit is contained in:
Mirror 2022-10-16 12:47:15 +03:00
commit 15b60eed34
8 changed files with 172 additions and 0 deletions

24
Makefile Normal file
View File

@ -0,0 +1,24 @@
ca:
openssl-3.0 req -x509 -new -nodes \
-newkey rsa:4096 -keyout pki/ca.key \
-sha256 -days 3650 -out pki/ca.crt \
-subj "/CN=MTLS TEST Root CA"
cp pki/ca.crt pkg/castore/ca.crt
server: server-cert
go build mtls/cmd/server
server-cert: ca
./cert.sh server
client: client-cert
go build mtls/cmd/client
client-cert: ca
./cert.sh client
all: server client
clean:
rm -r pki/* client server pkg/castore/ca.crt

6
Readme.md Normal file
View File

@ -0,0 +1,6 @@
# Golang mutual TLS example with local CA
## How to run
- run `make all` to build
- run `./server` command
- in separate terminal run `./client` command

13
cert.sh Executable file
View File

@ -0,0 +1,13 @@
#!/bin/env sh
openssl-3.0 req -new -nodes \
-out pki/$1.csr \
-keyout pki/$1.key \
-subj "/CN=MTLS TEST $1 certificate" \
-addext "basicConstraints=CA:FALSE" \
-addext "keyUsage=digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment" \
-addext "subjectAltName=DNS.1:$1,DNS.2:localhost"
openssl-3.0 x509 -req -in pki/$1.csr -out pki/$1.crt -copy_extensions copy \
-days 865 -sha256 \
-CA pki/ca.crt -CAkey pki/ca.key \
-CAcreateserial -CAserial pki/ca.srl

51
cmd/client/client.go Normal file
View File

@ -0,0 +1,51 @@
package main
import (
"crypto/tls"
"crypto/x509"
"io"
"log"
"mtls/pkg/castore"
"net/http"
"os"
)
var certPool *x509.CertPool
const (
CLIENT_CRT_FILE = "pki/client.crt"
CLIENT_KEY_FILE = "pki/client.key"
SERVER_ADDRESS = "https://localhost:8080/hello"
)
func main() {
log.Default().SetFlags(log.Lshortfile)
certPool = castore.NewCAstore()
clientKeyPair, err := tls.LoadX509KeyPair(CLIENT_CRT_FILE, CLIENT_KEY_FILE)
if err != nil {
log.Fatal(err)
}
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: certPool,
Certificates: []tls.Certificate{clientKeyPair},
},
},
}
resp, err := client.Get(SERVER_ADDRESS)
if err != nil {
log.Fatal(err)
}
for _, cert := range resp.TLS.PeerCertificates {
log.Printf("Peer certificate CommonName: %s", cert.Subject.CommonName)
}
_, err = io.Copy(os.Stdout, resp.Body)
if err != nil {
log.Fatal(err)
}
}

55
cmd/server/server.go Normal file
View File

@ -0,0 +1,55 @@
package main
import (
"crypto/tls"
"crypto/x509"
"log"
"mtls/pkg/castore"
"net/http"
)
var (
certPool *x509.CertPool
)
const (
SERVER_CRT_FILE = "pki/server.crt"
SERVER_KEY_FILE = "pki/server.key"
SERVER_ADDRESS = ":8080"
)
func main() {
log.Default().SetFlags(log.Lshortfile)
certPool = castore.NewCAstore()
mux := http.NewServeMux()
mux.HandleFunc("/hello", Hello_handler)
serverKeypair, err := tls.LoadX509KeyPair(SERVER_CRT_FILE, SERVER_KEY_FILE)
if err != nil {
log.Fatal(err)
}
server := http.Server{
TLSConfig: &tls.Config{
MinVersion: tls.VersionTLS13,
RootCAs: certPool,
ClientCAs: certPool,
Certificates: []tls.Certificate{serverKeypair},
ClientAuth: tls.RequireAndVerifyClientCert,
},
Addr: SERVER_ADDRESS,
Handler: mux,
}
err = server.ListenAndServeTLS("", "")
if err != nil {
log.Fatal(err)
}
}
func Hello_handler(w http.ResponseWriter, r *http.Request) {
for _, cert := range r.TLS.PeerCertificates {
log.Printf("Peer certificate CommonName: %s", cert.Subject.CommonName)
}
w.Write([]byte("Hello world\n"))
}

3
go.mod Normal file
View File

@ -0,0 +1,3 @@
module mtls
go 1.19

20
pkg/castore/castore.go Normal file
View File

@ -0,0 +1,20 @@
package castore
import (
"crypto/x509"
_ "embed"
"log"
"os"
)
//go:embed ca.crt
var CACert []byte
func NewCAstore() *x509.CertPool {
logger := log.New(os.Stderr, "", log.Lshortfile)
certPool := x509.NewCertPool()
if !certPool.AppendCertsFromPEM(CACert) {
logger.Fatal("Can't append CertPool with embedded CA")
}
return certPool
}

0
pki/.keep Normal file
View File