title: How to verify a certificate against an issuing chain in Go?
body: <p>I'd like to verify a PEM certificate against an issuing chain which is also a <code>.pem</code> file with several certificates separated by newline characters as shown in this gist, <a href="https://gist.github.com/kurtpeek/8bf3282e344c781a20c5deadac75059f" rel="nofollow noreferrer">https://gist.github.com/kurtpeek/8bf3282e344c781a20c5deadac75059f</a>. I've tried this with <code>Certpool.AppendCertsFromPEM</code> as follows:</p>
  
  <pre><code>package main
  
  import (
      "crypto/x509"
      "encoding/pem"
      "io/ioutil"
  
      "github.com/sirupsen/logrus"
  )
  
  func main() {
      caCertPEM, err := ioutil.ReadFile("issuing_chain.pem")
      if err != nil {
          logrus.WithError(err).Fatal("read CA PEM file")
      }
  
      certPEM, err := ioutil.ReadFile("3007e750-e769-440b-9075-41dc2b5b1787.pem")
      if err != nil {
          logrus.WithError(err).Fatal("read cert PEM file")
      }
  
      block, rest := pem.Decode(certPEM)
      if block == nil {
          logrus.WithField("rest", rest).Fatal("Decode CA PEM")
      }
  
      cert, err := x509.ParseCertificate(block.Bytes)
      if err != nil {
          logrus.WithError(err).Fatal("parse certificate")
      }
  
      roots := x509.NewCertPool()
      roots.AppendCertsFromPEM(caCertPEM)
  
      chain, err := cert.Verify(x509.VerifyOptions{Roots: roots})
      if err != nil {
          logrus.WithError(err).Fatal("failed to verify cert")
      }
  
      logrus.Infof("issuing chain: %+v", chain)
  }
  </code></pre>
  
  <p>However, if I run this I get the following error:</p>
  
  <pre><code>FATA[0000] failed to verify cert                         error="x509: certificate specifies an incompatible key usage"
  exit status 1
  </code></pre>
  
  <p>I believe this error is returned on line 790 of <a href="https://golang.org/src/crypto/x509/verify.go" rel="nofollow noreferrer">https://golang.org/src/crypto/x509/verify.go</a>:</p>
  
  <pre><code>if len(chains) == 0 {
      return nil, CertificateInvalidError{c, IncompatibleUsage, ""}
  }
  </code></pre>
  
  <p>In other words, the <code>Verify()</code> method is unable to build any <code>chains</code> from the options provided. I've tried splitting out the intermediates (the top two in the <code>issuing_chain.pem</code> shown in the gist) into a separate PEM file and adding those as <code>Intermediates</code> to the <code>x509.VerifyOptions</code>, but I still get the same error.</p>
  
  <p>What is the correct way to verify a certificate against an issuing chain in Go?</p>