title: Signing certificate request with certificate authority
body: <p>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.</p>
  
  <p>I've used this to create my Certificate Authority :</p>
  
  <pre><code>openssl genrsa -aes256 -out ca.key 4096
  openssl req -new -x509 -sha256 -days 730 -key ca.key -out ca.crt
  </code></pre>
  
  <p>Bob used this to create his certificate and certificate request :</p>
  
  <pre><code>openssl genrsa -out bob.key 4096
  openssl req -new -key bob.key -out bob.csr
  </code></pre>
  
  <p>I want to achive this, but in go :</p>
  
  <pre><code>openssl x509 -req -days 365 -sha256 -in bob.csr -CA ca.crt -CAkey ca.key -set_serial 3 -out bob.crt
  </code></pre>
  
  <p>For now, with theses commands, Bob can create a TLS connection to my API which use this tls.Config :</p>
  
  <pre><code>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 = &amp;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
  }
  </code></pre>
  
  <p>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 :</p>
  
  <pre><code>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))
  }
  </code></pre>
  
  <p>I spend some time to understand how openssl use the CA to create the CRT from the CRS, without success.</p>
  
  <p>Golang has a <a href="https://golang.org/pkg/crypto/x509/#CertificateRequest" rel="noreferrer">CertificateRequest object</a> from the crypto/x509 package that I can create with the <a href="https://golang.org/pkg/crypto/x509/#ParseCertificateRequest" rel="noreferrer">ParseCertificateRequest</a> but I can't find the function that take this object and my CA and return a certificate.</p>
  
  <p>Thank you for your help!</p>