I ended up figuring out what I needed to do. Here are some things that I 
did differently when it started working:

   - I created a self-signed root CA. This is possible with 
   generate_cert.go with one minor modification: the KeyUsage must include 
   x509.KeyUsageCertSign.
   - I created an intermediate CA. The x509.Certificate{} stuff was pretty 
   much the same as it was for the root CA. The main difference when creating 
   the intermediate CA certificate is that the x509.CreateCertificate call 
   looks more like x509.CreateCertificate(rand.Reader, &intermediateTemplate, 
   caCert, &intermediateTemplate.PublicKey, caKey) so the certificate will be 
   signed by the root CA instead of being another self-signed certificate.
   - I created a server certificate using the intermediate CA, using a 
   x509.CreateCertificate call similar to the one used to create the 
   intermediate CA: x509.CreateCertificate(rand.Reader, serverTemplate, 
   interCACert, serverTemplate.PublicKey, interCAKey). The x509.Certificate 
   looked like this:
   x509.Certificate{
     SerialNumber: big.NewInt(1),
     Subject: &pkix.Name{CommonName: "server.site.local"},
     NotBefore: notBefore,
     NotAfter: notAfter,
     KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
     ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
     IPAddresses: []net.IP{net.ParseIP("127.0.0.1")},
   }
   - I created a client certificate very similarly to how the server cert 
   was created: x509.CreateCertificate(rand.Reader, clientTemplate, 
   interCACert, clientTemplate.PublicKey, interCAKey). The x509.Certificate 
   looked like this:
   x509.Certificate{
     SerialNumber: big.NewInt(1),
     Subject: &pkix.Name{CommonName: "client.site.local"},
     NotBefore: notBefore,
     NotAfter: notAfter,
     KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
     ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
   }
   - When I created the server, the TLS config had a x509.CertPool 
   containing the intermediate CA certificate as the ClientCAs
   - When I created the client, the TLS config had a x509.CertPool 
   containing the intermediate CA certificate as the RootCAs

I did end up using x509.CertificateRequests to generate the server and 
client certificates. They aren't nearly as complicated as I tried to make 
them at first. Basically, I just used the x509.CertificateRequest's 
PublicKey and Subject to set those attributes when creating the 
x509.Certificate. Done and done.


I hope that helps anyone who stumbles upon this thread having similar 
problems.


- Josh

On Wednesday, August 17, 2016 at 10:01:01 AM UTC-6, Josh V wrote:
>
> Hi all,
>
> I'm trying to come up with an example of how to create SSL certificates 
> and keys from start to finish (including CertificateRequests) all using Go. 
> I'll go ahead and get the obligatory "I'm pretty new to SSL" disclaimer out 
> of the way... I've played with 
> https://golang.org/src/crypto/tls/generate_cert.go quite a bit trying to 
> understand what all needs to happen, but that program doesn't cover some 
> cases I'd like to get working. Here's what I would like to build:
>
>    - Server piece
>       - Generates a new private
>       - Generates a new x509.Certificate (with IsCA: true) using the new 
>       private key
>       - Write both the cert and key to disk
>       - Spin up an HTTP server to accept CSR->Certificate requests
>       - Spin up an HTTPS server to accept requests from clients to test 
>       their newly generated certificates
>    - Client piece
>       - Generates a new private key
>       - Creates a x509.CertificateRequest
>       - POSTs the CertificateRequest off to the server's HTTP piece
>       - Receives a response containing the client's fresh Certificate
>       - Writes both the cert and the key to disk
>       - Successfully connects to the server's HTTPS piece using the newly 
>       generated certificate
>    
> I've been working on a project that basically does (or tries to do) all of 
> this, and things were looking promising for a while. I have (I guess what 
> you'd call) a "root CA" cert/key that are used to create new client 
> certificates from CSRs. The resulting client certificate, client key, and 
> CA certificate connect to my server piece just fine when I use curl. But 
> when I try to use those same files in the Go client, I get an "x509: 
> certificate signed by unknown authority" error. I've tried as many 
> variations on the tls.Config.ClientCAs and RootCAs as I can think of. 
> Nothing seems to be just right, so I'm obviously missing something.
>
> I've tried to whittle my project down to the basic concepts described 
> above, which can be found at 
> https://gist.github.com/codekoala/c793f020c27bded785fb39f0f2594ee2 ... I 
> apologize in advance--it is horrendous code with lots of copy pasta and 
> unhandled error cases. I just need to get this out there. If anyone can 
> muster up the courage to take a peek at that gist and offer suggestions for 
> how to achieve what I've described, please do.
>
> I realize most people will immediately suggest "just use openssl on the 
> command line" to get past these hurdles. I could certainly do that, but I'd 
> prefer to keep it all in the standard library, if at all possible. Also, 
> from my research, it seems like I should be making a root CA and then an 
> intermediate CA that is used to process the actual CSRs and such. If anyone 
> can offer insight into the correct way to do that with Go, I'm all eyes.
>
> Thanks!
>
> - Josh
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to