Reputation: 10681
I have a collection of pem certs in a string, that I want to bind to a TLS endpoint, how can I effectively convert them to CRT files (i.e.public.crt) and key file (i.e. private.key), for binding it to the endpoint:
Input string:
-----BEGIN PRIVATE KEY-----
MIIE3oydueOANJHhvL3yvJdTphoev5GO7go+ByYOO/l54u5O2PxMeX+AjAb6Axmq
livIuhw=
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIE3oydueOANJHhvL3yvJdTphoev5GO7go+ByYOO/l54u5O2PxMeX+AjAb6Axmq
livIuhw=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIE3oydueOANJHhvL3yvJdTphoev5GO7go+ByYOO/l54u5O2PxMeX+AjAb6Axmq
asdsa312asdsadasdsad=
-----END CERTIFICATE-----
My code to bind would be:
https_r := mux.NewRouter()
err_https := http.ListenAndServeTLS(serviceEndpoint, "/etc/pki/tls/certs/public.crt", "/etc/pki/tls/certs/private.key", https_r)
if err_https != nil {
log.Fatal("Web server (HTTPS): ", err_https)
}
I have tried two approaches:
Ideally, I would not like to perform a bunch of string parsing, which would be prone to break.
Any other way would highly be appreciated.
Upvotes: 6
Views: 6605
Reputation: 4189
I tried to decode it to a PEM block, but it only reads one of the certs and drops the rest.
The trick is to handle the rest of the PEM blocks. It is returned in pem.Decode
seconds result. Here is how it can be done:
for block, rest := pem.Decode(data); block != nil; block, rest = pem.Decode(rest) {
switch block.Type {
case "CERTIFICATE":
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
panic(err)
}
// Handle certificate
fmt.Printf("%T %#v\n", cert, cert)
case "PRIVATE KEY":
key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
panic(err)
}
// Handle private key
fmt.Printf("%T %#v\n", key, key)
default:
panic("unknown block type")
}
}
Upvotes: 8