google / go-attestation

Apache License 2.0
350 stars 86 forks source link

Getting wrapped private key after certificate generation #377

Closed Mangelmesa closed 2 months ago

Mangelmesa commented 2 months ago

Hello everyone and thanks for the great work in this library. I'm having some trouble where I am unable to export the wrapped private key that corresponds to a generated certificate. Here's what I am trying to do:

  1. First, I've generated a key using this library's function NewKey.
  2. With the resulting key, it is possible to use the private part to sign a certificate signing request (CSR) using the x509 library and the CreateCertificateRequest function.
  3. Externally, using OpenSSL, I can sign this CSR to get a valid certificate.
  4. The problem comes while getting the wrapped private key that corresponds to the certificate that was generated. I understand that the private key resides inside of the TPM and that it cannot be extracted, but for example, using the command: openssl genpkey -provider tpm2 -algorithm RSA -out example.key a TPM wrapped key with the header TSS2 PRIVATE KEY can be obtained and used.

I see that it is possible to export the blobs (TPM2B_PUBLIC and TPM2B_PRIVATE), and that the private key can be loaded at a later time in GO, but I don't see an option to export the wrapped key to a file, which I would need for another software that establishes an mTLS connection. Is there any way to get the corresponding wrapped private key in GO? Does this make sense? I've checked here and in the go-tpm library but I don't see any way of achieving this. Any help is greatly appreciated!

Mangelmesa commented 2 months ago

Just adding some information to close this issue, since I ended up getting it to work.

Using the Blobs function from this library, the TPM2B_PUBLIC and TPM2B_PRIVATE can be generated and stored in 2 different binary files. The tpm2-tools Linux utility includes the tpm2_encodeobject CLI function to encode the public and private portions in the PEM format used by tss2. This function requires a context, in this case we can point it to the SRK (0x81000001), the portions that were stored in the files, and the output combined file:

tpm2_encodeobject -C 0x81000001 -u key.pub -r key.priv -o out.pem

In my case, it did not work first try, as the blobs lacked 2 bytes each at the start for them to have the correct format (I am not an expert in ASN.1, this is my basic understanding of it). After adding these bytes and calling the tpm2_encodeobject, the correct wrapped key is generated. I'm sure there are cleaner ways of doing this, but this is what worked for me for now.