Skip to content

Instantly share code, notes, and snippets.

@KarolBedkowski
Created May 21, 2020 21:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KarolBedkowski/826b44bba9971eb7b3807a747225a097 to your computer and use it in GitHub Desktop.
Save KarolBedkowski/826b44bba9971eb7b3807a747225a097 to your computer and use it in GitHub Desktop.
// Simple HTTPS server for verifying client connections.
package main
import (
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/http/httputil"
"strings"
)
func createTLSConfig(ca string) (*tls.Config, error) {
caCertPEM, err := ioutil.ReadFile(ca)
if err != nil {
return nil, err
}
roots := x509.NewCertPool()
ok := roots.AppendCertsFromPEM(caCertPEM)
if !ok {
panic("failed to parse root certificate")
}
return &tls.Config{
ClientAuth: tls.VerifyClientCertIfGiven,
ClientCAs: roots,
}, nil
}
func formatCertName(name pkix.Name) string {
return fmt.Sprintf("/C=%s/ST=%s/L=%s/O=%s/OU=%s/CN=%s/",
name.Country, name.Province, name.Locality, name.Organization,
name.OrganizationalUnit, name.CommonName)
}
func formatCert(idx int, cert *x509.Certificate) string {
res := []string{
fmt.Sprintf(" %d\n s/n=%d (%x)\n ver: %d ", idx, cert.SerialNumber,
cert.SerialNumber, cert.Version),
" subject: " + formatCertName(cert.Subject),
" issuer: " + formatCertName(cert.Issuer),
fmt.Sprintf(" valid: %s - %s", cert.NotBefore, cert.NotAfter),
}
return strings.Join(res, "\n")
}
func defaultHandler(w http.ResponseWriter, r *http.Request) {
res := make([]string, 0, 30)
res = append(res, fmt.Sprintf("HTTP Method: %s", r.Method))
res = append(res, fmt.Sprintf("HTTP URL: %s", r.URL))
res = append(res, fmt.Sprintf("HTTP Proto: %s", r.Proto))
for k, h := range r.Header {
res = append(res, fmt.Sprintf("Header %s=%v", k, h))
}
res = append(res, fmt.Sprintf("HTTP Host: %s", r.Host))
res = append(res, fmt.Sprintf("HTTP Remote: %s", r.RemoteAddr))
state := r.TLS
if state != nil {
res = append(res, fmt.Sprintf("TLS Version: %x", state.Version))
res = append(res, fmt.Sprintf("TLS HandshakeComplete: %t", state.HandshakeComplete))
res = append(res, fmt.Sprintf("TLS DidResume: %t", state.DidResume))
res = append(res, fmt.Sprintf("TLS CipherSuite: %x", state.CipherSuite))
res = append(res, fmt.Sprintf("TLS NegotiatedProtocol: %s", state.NegotiatedProtocol))
res = append(res, fmt.Sprintf("TLS NegotiatedProtocolIsMutual: %t", state.NegotiatedProtocolIsMutual))
res = append(res, "Certificate chain:")
for i, cert := range state.PeerCertificates {
res = append(res, formatCert(i, cert))
}
} else {
res = append(res, "NO TLS")
}
res = append(res, "HTTP Request-------------------------")
if dump, err := httputil.DumpRequest(r, true); err == nil {
res = append(res, string(dump))
} else {
res = append(res, fmt.Sprintf("Err: %s", err.Error()))
}
res = append(res, "HTTP Request END --------------------")
for _, r := range res {
log.Println(r)
}
w.WriteHeader(http.StatusFound)
w.Write([]byte(strings.Join(res, "\n")))
}
func main() {
listen := flag.String("listen", "localhost:4443", "addres:port to listen")
ca := flag.String("ca", "./ca.crt", "CA certificate")
crt := flag.String("cert", "./server.crt", "server certificate")
key := flag.String("key", "./server.key", "server key")
flag.Parse()
config, err := createTLSConfig(*ca)
if err != nil {
log.Fatal("tls config failed: %s", err.Error())
}
http.HandleFunc("/", defaultHandler)
server := &http.Server{
Addr: *listen,
TLSConfig: config,
}
log.Println("Starting listen: ", *listen)
if err := server.ListenAndServeTLS(*crt, *key); err != nil {
log.Fatal("Listen error: ", err.Error())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment