I want to use TLS mutual authentication to authenticate a client on a API made in go. I've created a certificate authority, and let's say Bob has a key pair he wants to use with the client. Bob created a certificate request and want me to validate his certificate in order to be authorized and authenticated on the API.
I've used this to create my Certificate Authority :
openssl genrsa -aes256 -out ca.key 4096 openssl req -new -x509 -sha256 -days 730 -key ca.key -out ca.crt Bob used this to create his certificate and certificate request :
openssl genrsa -out bob.key 4096 openssl req -new -key bob.key -out bob.csr I want to achive this, but in go :
openssl x509 -req -days 365 -sha256 -in bob.csr -CA ca.crt -CAkey ca.key -set_serial 3 -out bob.crt For now, with theses commands, Bob can create a TLS connection to my API which use this tls.Config :
func createTLSConfig(certFile string, keyFile string, clientCAFilepath string) (config *tls.Config, err error) { cer, err := tls.LoadX509KeyPair(certFile, keyFile) if err != nil { return nil, err } clientCAFile, err := ioutil.ReadFile(clientCAFilepath) if err != nil { return nil, err } clientCAPool := x509.NewCertPool() clientCAPool.AppendCertsFromPEM(clientCAFile) config = &tls.Config{ Certificates: []tls.Certificate{cer}, ClientAuth: tls.RequireAndVerifyClientCert, ClientCAs: clientCAPool, CipherSuites: []uint16{ tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, }, PreferServerCipherSuites: true, SessionTicketsDisabled: false, MinVersion: tls.VersionTLS12, CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384}, } return config, nil } But what if Julia now want to login ? She will have to create a CSR, send it to me and I would have to manually validate her CSR to a CRT too. To avoid this manual operation, the idea is to have a register endpoint where Julia can submit her CSR and get back a valid CRT. The endpoint will basically look like this :
func Register(c echo.Context) (err error) { // get Julia's csr from POST body csr := certificateFromBody(c.Body) // valid csr with ca to generate the crt crt := signCSR(csr, config.ClientCAPath) // return the crt to julia return c.JSON(http.StatusCreated, base64.StdEncoding.EncodeToString(crt)) } I spend some time to understand how openssl use the CA to create the CRT from the CRS, without success.
Golang has a CertificateRequest object from the crypto/x509 package that I can create with the ParseCertificateRequest but I can't find the function that take this object and my CA and return a certificate.
Thank you for your help!