Basic application that uses a the tpm2-tss-engine to perform RSA encryption and signatures.
This is intended to run on a system with a TPM as well as the the openssl engine library installed. The TPM-based private key is generated directly using tpm2tss-genkey
and from that, the openssl engine to surface the public part. The tpm2-tss-engine surfaces the OpenSSL constructs like EVP_PKEY_RSA
so you can directly use that against the TPM
Also included:
gcp_jwt_token
: application that uses a Google Cloud ServiceAccount embedded within a TPM to sign a JWT. This JWT can then be used to access a google cloud resource such as Pub/Subgcp_oidc_token
: application that uses a Google Cloud ServiceAccount embedded within a TPM to sign a JWT and then exchange it for a Google Issued OIDC token. This oidc token can be used to authenticate against user-deployed resources behind Cloud Run, Cloud Functions, etc. For more information, see google-oidc-tokenAs its a basic helloworld app (and because i really don’t know c, caveat emptor)
You can find the source here
On system that has a TPM you don’t mind messing with, (in this example a google cloud ShieldedVM
gcloud compute instances create shielded-5 --zone=us-central1-a --machine-type=n1-standard-1 --subnet=default --network-tier=PREMIUM --no-service-account --no-scopes --image=ubuntu-1804-bionic-v20191002 --image-project=gce-uefi-images --no-shielded-secure-boot --shielded-vtpm --shielded-integrity-monitoring
tpm2-tss
and tpm2-tss-engine
sudo su -
apt-get update && apt -y install \
build-essential \
autoconf \
autoconf-archive \
automake \
m4 \
libtool \
gcc \
pkg-config \
libssl-dev \
pandoc \
doxygen \
git \
libcurl4-openssl-dev
cd
git clone https://github.com/tpm2-software/tpm2-tss.git
cd tpm2-tss
./bootstrap
./configure --with-udevrulesdir=/etc/udev/rules.d
make -j$(nproc)
make install
udevadm control --reload-rules && sudo udevadm trigger
ldconfig
cd
git clone https://github.com/tpm2-software/tpm2-tss-engine.git
cd tpm2-tss-engine
./bootstrap
./configure
make -j$(nproc)
sudo make install
cd
touch /root/.rnd
tpm2tss-genkey -a rsa private.tss
openssl req -new -x509 -engine tpm2tss -key private.tss -keyform engine -out public.crt -subj "/C=SM/ST=somecountry/L=someloc/O=someorg/OU=somedept/CN=example.com"
openssl x509 -pubkey -noout -in public.crt > public.pem
openssl x509 -in public.crt -text -noout
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/x86_64-linux-gnu/engines-1.1/
gcc tpm_encrypt_decrypt.c -L/usr/lib/x86_64-linux-gnu/engines-1.1/ -lcrypto -ltpm2tss -o tpm_encrypt_decrypt
gcc tpm_sign_verify.c -L/usr/lib/x86_64-linux-gnu/engines-1.1/ -lcrypto -ltpm2tss -o tpm_sign_verify
./tpm_encrypt_decrypt
./tpm_sign_verify
I’ve left commented out sections in the code that shows how the operations run while reading non-TPM based keys
gcp_jwt_token/gcs_auth.c
is a sample application that provides a Google Cloud Platform JWT Access Token.
To use this mode, you’ll also need tpm2-tools
install TPM2-Tools
https://github.com/tpm2-software/tpm2-tools/blob/master/INSTALL.md
You can either
.p12
file and embed the private part to the TPM
orOption 2 has some distinct advantages: the private key would have never left the TPM at all…it was generated on the TPM….However, you have to be careful to import the public key and associate that public key with the service account. What that means is you need to employ controls to assure that the public key you will import infact is the one that is associated with the TPM.
Anyway, either do (A) or (B) below (A is easier)
Download Service account .p12 file
Extract public/private keypair
openssl pkcs12 -in svc_account.p12 -nocerts -nodes -passin pass:notasecret | openssl rsa -out private.pem
openssl rsa -in private.pem -outform PEM -pubout -out public.pem
tpm2_createprimary -C o -g sha256 -G rsa -c primary.ctx
tpm2_import -C primary.ctx -G rsa -i private.pem -u key.pub -r key.prv
tpm2_load -C primary.ctx -u key.pub -r key.prv -c key.ctx
tpm2_evictcontrol -C o -c key.ctx 0x81010002
tpm2_createprimary -C e -g sha256 -G rsa -c primary.ctx
tpm2_create -G rsa -u key.pub -r key.priv -C primary.ctx
tpm2_load -C primary.ctx -u key.pub -r key.priv -c key.ctx
tpm2_evictcontrol -C o -c 0x81010002
tpm2_evictcontrol -C o -c key.ctx 0x81010002
tpm2_readpublic -c key.ctx -f PEM -o key.pem
x509
certificateYou can use certgen.go here. Remember to use
r, err := saltpm.NewTPMCrypto(&saltpm.TPM{
TpmDevice: "/dev/tpm0",
TpmHandle: 0x81010002,
})
the output should be just cert.pem
which is infact just the x509 certificate we will use to import
go run certgen.go
2019/11/28 00:49:55 Creating public x509
2019/11/28 00:49:55 wrote cert.pem
x509
cert to GCP for a given service account (note YOUR_SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com
must exist prior to this step)The following steps are outelined here.
gcloud alpha iam service-accounts keys upload cert.pem --iam-account YOUR_SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com
Verify…you should see a new certificate. Note down the KEY_ID
$ gcloud iam service-accounts keys list --iam-account=YOUR_SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com
KEY_ID CREATED_AT EXPIRES_AT
a03f0c4c61864b7fe20db909a3174c6b844f8909 2019-11-27T23:20:16Z 2020-12-31T23:20:16Z
9bd21535c9985ad922c1cf6bb3dbceef0f7375d6 2019-11-28T00:49:55Z 2020-11-27T00:49:55Z <<<<<<<
7077c0c9164252fcfb73d8ccbd68f8c97e0ffee6 2019-11-27T23:15:32Z 2021-12-01T05:43:27Z
Edit issuer,subject,audience fields incode below Get the issuer, subject email for the service account and apply it into code below.
Compile
apt-get install libcurl4-openssl-dev libssl-dev
git clone https://github.com/DaveGamble/cJSON.git
cd cJSON
make
make install
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/x86_64-linux-gnu/engines-1.1
default: gcc gcs_auth.c -lcrypto -lcjson -o gcs_auth
or with a TPM (requires tpm2-tss-engine installed)
gcc gcs_auth.c -L/usr/lib/x86_64-linux-gnu/engines-1.1/ -lcrypto -lcjson -ltpm2tss -o gcs_auth
./gcs_auth
export TOKEN=<..>
curl -v -H "Authorization: Bearer $TOKEN" -H "pubsub.googleapis.com" -o /dev/null -w "%{http_code}\n" https://pubsub.googleapis.com/v1/projects/yourPROJECT/topics
Follow steps 1->3 above, edit google_oidc.c
and specify issuer
, subject
, target_audience
:
gcc google_oidc.c -L/usr/lib/x86_64-linux-gnu/engines-1.1/ -lcrypto -lcjson -ltpm2tss -lcurl -o google_oidc
This site supports webmentions. Send me a mention via this form.