update certpool at server runtime

Viewed 154

Hi I am interested in adding certificates to the certPool while the server is running, but it seems like it's not picked up. Do I need to relaunch the server for this to work?

package main

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

func main() {
    handler := http.NewServeMux()
    // verify the cert if given (or check for jwt token)
    handler.HandleFunc("/auth", func(w http.ResponseWriter, r *http.Request) {
        if certs := r.TLS.PeerCertificates; len(certs) > 0 {
            cert := certs[0]
            fmt.Println(cert.Subject.CommonName)
            w.WriteHeader(http.StatusOK)
            fmt.Fprintln(w, "Cert Valid")
            return
        }
        //  ...
    })
    
    // the cert pool that holds the client CAs
    certPool := x509.NewCertPool()

    // post a new CA and add it to the pool
    handler.HandleFunc("/ca", func(rw http.ResponseWriter, r *http.Request) {
        caCertFile, err := ioutil.ReadAll(r.Body)
        if err != nil {
            log.Printf("error reading CA certificate: %v", err)
            rw.WriteHeader(http.StatusUnprocessableEntity)
            return
        }
        certPool.AppendCertsFromPEM(caCertFile)
        rw.WriteHeader(http.StatusCreated)
    })

    server := http.Server{
        Addr:    ":9090",
        Handler: handler,
        TLSConfig: &tls.Config{
            ClientAuth: tls.VerifyClientCertIfGiven,
            ClientCAs:  certPool,
            MinVersion: tls.VersionTLS12,
        },
    }

    if err := server.ListenAndServeTLS("certs/server/tls.crt", "certs/server/tls.key"); err != nil {
        log.Fatalf("error listening to port: %v", err)
    }
}

I am posting the cert with curl

curl -k -X POST https://localhost:9090/ca -d @test-ca.pem

Based, on one comment, I have tried the below but it doesn't seem to work either.

certFile, err := ioutil.ReadFile("certs/server/tls.crt")
if err != nil {
    log.Fatal(err)
}

keyFile, err := ioutil.ReadFile("certs/server/tls.key")
if err != nil {
    log.Fatal(err)
}

cert, err := tls.X509KeyPair(certFile, keyFile)
if err != nil {
    log.Fatal(err)
}

listener, err := tls.Listen("tcp", ":9090", &tls.Config{
    ClientAuth:   tls.VerifyClientCertIfGiven,
    ClientCAs:    certPool,
    Certificates: []tls.Certificate{cert},
})
if err != nil {
    log.Fatalf("error creating listener: %v", err)
}

if err = http.Serve(listener, handler); err != nil {
    log.Fatalf("error serving: %v", err)
}
0 Answers
Related