// server.go
package main

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"log"
	"net/http"
	"os"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
	if len(r.TLS.PeerCertificates) > 0 {
		client := r.TLS.PeerCertificates[0]
		ret := fmt.Sprintf(
			"Common Name: %s\nOrganization Unit: %s\nSerial Number: %s\n",
			client.Subject.CommonName,
			client.Subject.OrganizationalUnit[0],
			client.SerialNumber.Text(16))
		fmt.Fprintf(w, ret)
		log.Printf("Client CN: %s, OU: %s, Serial: %s\n",
			client.Subject.CommonName,
			client.Subject.OrganizationalUnit[0],
			client.SerialNumber.Text(16))
		return
	}

	w.WriteHeader(http.StatusUnauthorized)
	fmt.Fprintf(w, `{ "error": "client certificate required" }`)
}

func main() {
	cert, err := tls.LoadX509KeyPair("server.pem", "server.key")
	if err != nil {
		log.Fatalf("Erro ao carregar certificado do servidor: %v", err)
	}

	caCert, err := os.ReadFile("ca.pem")
	if err != nil {
		log.Fatalf("Erro ao ler CA cert: %v", err)
	}
	caCertPool := x509.NewCertPool()
	if ok := caCertPool.AppendCertsFromPEM(caCert); !ok {
		log.Fatalf("Erro ao adicionar CA cert ao pool")
	}

	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{cert},
		ClientCAs:    caCertPool,
		ClientAuth:   tls.RequireAndVerifyClientCert,
	}

	server := &http.Server{
		Addr:      ":8080",
		TLSConfig: tlsConfig,
	}

	http.HandleFunc("/", helloHandler)

	log.Printf("Listening on %s\n", server.Addr)
	log.Fatal(server.ListenAndServeTLS("", ""))
}
