GCS signedURLs and GCP Authentication with Trusted Platform Module

Samples in golang that enables the following where the private key or hmac secret is embedded with a TPM (Trusted Platform Module)

HMAC SignedURLs:

  • Import a GCS HMAC secret and use it to generate a SignedURL

RSA SignedURL:

  • Generate an RSA Private Key on a TPM
  • Use RSA Private Key on TPM to create either:
  • a) Certificate Signing Request (CSR) for signing by another CA
  • b) Self Signed x509 Certificate
  • Associate Certificate with a ServiceAccount
  • Generate SignedURL using TPM
  • Access GCS Object

Oauth2 AccessToken

  • Generate Certificate on TPM (step2)
  • Generate GCP oauth2 token using TPM based service account
  • Access GCS using google-cloud-storage library

this repository is not supported by Google

You can find the source here:

References

Setup

Create GCS Bucket, object and Service Account and HMAC key to test with

export PROJECT_ID=`gcloud config get-value core/project`
export PROJECT_NUMBER=`gcloud projects describe $PROJECT_ID --format='value(projectNumber)'`
# create a gcs bucket and object
gsutil mb gs://$PROJECT_ID-tpm
echo -n "some text" > somefile.txt
gsutil cp somefile.txt gs://$PROJECT_ID-tpm
# create a service account that has access to a bucket
# the private key on the TPM will be associated with this service account
gcloud iam service-accounts create tpm-svc-account --project $PROJECT_ID
gcloud iam service-accounts keys list --iam-account tpm-svc-account@$PROJECT_ID.iam.gserviceaccount.com
# allow the service account access to the bucket
gsutil iam ch serviceAccount:tpm-svc-account@$PROJECT_ID.iam.gserviceaccount.com:objectViewer gs://$PROJECT_ID-tpm
# remember the hmac key and secret
gsutil hmac create tpm-svc-account@$PROJECT_ID.iam.gserviceaccount.com
Access ID: GOOG1EJBAWIATBBMPW5SNXGTKD6QTQPNJ3MDJXGGGQTJ6PYQQ3I4UGWIZYHBQ
Secret: ...redacted...
gsutil hmac list -p $PROJECT_ID# Create a VM with a TPM
gcloud compute instances create tpm-test \
--image=debian-10-buster-v20210701 --image-project=debian-cloud \
--machine-type "n1-standard-1" \
--shielded-secure-boot --shielded-vtpm --shielded-integrity-monitoring \
--zone us-central1-a
# ssh to the VM
gcloud compute ssh tpm-test --zone us-central1-a

On VM:

sudo su -
apt-get update -y
apt-get install wget curl git -y
# install golang 1.15 https://golang.org/doc/install
wget https://golang.org/dl/go1.15.14.linux-amd64.tar.gz
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.15.14.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
## *optionally* install tpm2_tools https://tpm2-tools.readthedocs.io/en/latest/INSTALL/# get the source
git clone https://github.com/salrashid123/gcs_tpm.git
cd gcs_tpm

HMAC

Embed the HMAC key into the TPM

# first import the hmac secret to the TPM
go run main.go --mode=import --hmacSecret="hmac_secret_from_setup"
# now use the TPM to generate a signedURL and download the file
go run main.go --mode=sign \
--hmacKey="GOOG1EJBAWIATBBMPW5SNXGTKD6QTQPNJ3MDJXGGGQTJ6PYQQ3I4UGWIZYHBQ" \
--bucketName="$PROJECT_ID-tpm" --objectName="somefile.txt"

At this point the hmac key is embedded into the TPM with set TPM attributes

public := tpm2.Public{
Type: tpm2.AlgKeyedHash,
NameAlg: tpm2.AlgSHA256,
AuthPolicy: []byte(defaultPassword),
Attributes: tpm2.FlagFixedTPM | tpm2.FlagFixedParent | tpm2.FlagUserWithAuth | tpm2.FlagSign, // | tpm2.FlagSensitiveDataOrigin
KeyedHashParameters: &tpm2.KeyedHashParams{
Alg: tpm2.AlgHMAC,
Hash: tpm2.AlgSHA1,
},
}

You can also set TPM Policies that govern how to access the key (eg, passwordPolicy, PCR Policy, etc)

If you want to use tpm2_tools, note that tpm support was added in with Issue 1597

Service Account RSA

The following will create an RSA private key on the tpm and then use that to create a Certificate Signing Request (CSR) and a self-signed x509 Certificate. The CSR is NOT used in this sample but could be used by an external CA to sign. For this repo, we will use the TPM based RSA key to self-sign a certificate.

Since this procedure uploads a key, your organization policy should allow type: constraints/iam.disableServiceAccountKeyUpload

# generate the 509
go run svcaccount/main.go --mode=gencert --cn=tpm-svc-account@$PROJECT_ID.iam.gserviceaccount.com
# this will generate the cert file at `x509cert.pem`
# copy x509cert.pem to laptop
# on LAPTOP, upload the 509 cert and associate it with a service account
gcloud beta iam service-accounts keys upload x509cert.pem --iam-account=tpm-svc-account@$PROJECT_ID.iam.gserviceaccount.com
gcloud iam service-accounts keys list --iam-account tpm-svc-account@$PROJECT_ID.iam.gserviceaccount.com
KEY_ID CREATED_AT EXPIRES_AT
4909a11e0a0793f7daba01958a93e67c34cddff6 2021-08-02T12:52:00Z 2022-08-02T12:52:00Z <<< TPM based service account
1155f398f6bf840e84a9e16effa35aceca6f45a8 2021-08-02T12:26:22Z 2023-08-25T01:58:04Z
# on VM
# A) generate a signedURL and access the object
go run svcaccount/main.go --mode=genurl --cn=tpm-svc-account@$PROJECT_ID.iam.gserviceaccount.com --bucketName=$PROJECT_ID-tpm --objectName=somefile.txt
# B) use the TPM's private key to generate a GCP oauth access_token
go run svcaccount/main.go --mode=useclient --cn=tpm-svc-account@$PROJECT_ID.iam.gserviceaccount.com --bucketName=$PROJECT_ID-tpm --objectName=somefile.txt

with SignedURL

with oauth2 token

Appendix

The equivalent commands using openssl-tss engine to that will generate and embed hmac and RSA keys are

  • RSA
# verify TPM support
openssl engine -t -c tpm2tss
# generate a private key on TPM
tpm2tss-genkey -a rsa private.tss
# generate CSR
openssl req -new -out csr.pem -engine tpm2tss -keyform engine -key private.tss
# generate self-signed certificate
openssl req -new -x509 -engine tpm2tss -key private.tss -keyform engine -out public.crt -subj "/C=US/ST=California/L=Mountain View/O=Acme Co/OU=Enterprise/CN=OURServiceAccountName@PROJECT_ID.iam.gserviceaccount.com"
# extract RSA publickey from certificate
openssl x509 -pubkey -noout -in public.crt > public.pem
# print certificate
openssl x509 -in public.crt -text -noout
# start SSL listener using TPM-based private key
openssl s_server -cert public.crt -key private.tss -keyform engine -engine tpm2tss -accept 50051
  • HMAC
export secret="key"
export plain="The quick brown fox jumps over the lazy dog"
echo -n $secret > hmac.key
hexkey=$(xxd -p -c 256 < hmac.key)
echo $hexkey
echo -n $plain > data.inopenssl dgst -sha256 -mac hmac -macopt hexkey:$hexkey data.in
HMAC-SHA256(data.in)= f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
tpm2 createprimary -Q -G rsa -g sha256 -C e -c primary.ctxtpm2 import -C primary.ctx -G hmac -i hmac.key -u hmac.pub -r hmac.priv
tpm2 load -C primary.ctx -u hmac.pub -r hmac.priv -c hmac.ctx
echo -n $plain | tpm2_hmac -g sha256 -c hmac.ctx | xxd -p -c 256
f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8

--

--

--

A collection of technical articles and blogs published or curated by Google Cloud Developer Advocates. The views expressed are those of the authors and don't necessarily reflect those of Google.

Recommended from Medium

Gartner: global RPA software revenue to reach US$2bn in 2021

Tools for Effective Remote Work

Como la latinidad cambiará nuestras vidas

Data Fusion Private Cluster to access public source

No more ‘Easy Bake Oven’ coding

Code in Swift on iPad in Kindergarten

How I Accepted I’m Disabled – And Why It Took So Long.

Android Stack at Kapten

What’s New at AWS for 2022 — Introduction to Readable Standby Instances in RDS

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
salmaan rashid

salmaan rashid

More from Medium

Reduce DB upgrade downtime to less than 10 minutes using DMS on Google Cloud

Kickstart Clickhouse in Google Cloud Platform — GCP

Cloud Monitoring, We Need to Chat

Understanding Google Cloud IAM concepts with stick figures