Reputation: 487
I have created a service account key for a GCP service account using the Terraform google
provider. I've set the private key type to "TYPE_PKCS12_FILE"
, which we require for compatibility with an existing application.
When I was testing this as a PoC, I created the P12 key though the console, and it worked with no issues. Now, I want to handle key generation in our Terraform script, and I cannot get a working P12 key. The actual key resource is created, and it contains a public_key
field, which can be base64 decoded to a valid RSA certificate, and a private_key
, which is supposedly a P12 file which has been base64 encoded, if I am reading the documentation properly.
I have tried saving the private_key
value from Terraform into a file, and base64 decoding it manually. It superficially resembles a known valid P12 bundle, but it is reported as an invalid certificate when I try to import it anywhere.
The object in the state looks like:
"private_key": "MIIJ[...]GoA==",
"private_key_type": "TYPE_PKCS12_FILE",
"public_key": "LS0t[...]LQo=",
"public_key_data": null,
"public_key_type": "TYPE_X509_PEM_FILE",
So, how do I turn the private_key
from the Terraform resource into a usable P12 file that can be uploaded to our application?
Upvotes: 3
Views: 1358
Reputation: 487
Answering this question for myself because the specific error received from Terraform needs some explanation. If you try to use TF's built-in base64decode()
function on the private key, it gives the error "the result of decoding the provided string is not valid UTF-8"
.
I originally assumed that this was an error with the cert, because I had thought that I was expecting the private key to be a PEM certificate, but the private_key
value actually contains the full P12 bundle.
The basic operation of decoding that string as base64 is correct, but as it turns out, Terraform only supports a limited range of encodings. Decoding to a P12 bundle is not supported in Terraform, because TF parses the output of the base64decode()
call to confirm it is valid and it cannot validate the encoding of a P12, since that encoding is not supported.
The solution is to save the output string of the private_key
property into a txt file, then use a certificate management tool like openssl
or certutil
to handle the decoding.
Example:
certutil -decode please-decode-me.txt my-mydecoded-cert.p12
EDIT: Also, note that at minimum, the encode/decode extensions for VS Code do NOT handle that operation correctly for P12 files. I tried that approach thinking that those operations would leave the underlying data of the file unchanged and simply parse it again with a different encoding. This is incorrect, it will change the file data to match the "symbol not found" glyph wherever that glyph is used.
I assume this is well known and/or obvious for security specialists, but I thought I'd explicitly mention it in case it's of use to any other SREs or application devs who don't interact with certificate automation on a regular basis.
Upvotes: 2