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