{"id":21354910,"url":"https://github.com/salrashid123/go_tpm_https_embed","last_synced_at":"2025-07-12T22:32:18.252Z","repository":{"id":91310000,"uuid":"315352939","full_name":"salrashid123/go_tpm_https_embed","owner":"salrashid123","description":"TPM based mTLS","archived":false,"fork":false,"pushed_at":"2024-06-17T11:28:00.000Z","size":338,"stargazers_count":9,"open_issues_count":0,"forks_count":5,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-06-17T12:52:54.250Z","etag":null,"topics":["certificate","golang","tls","trusted-computing","trusted-platform-module"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/salrashid123.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-11-23T15:10:42.000Z","updated_at":"2024-06-17T11:28:03.000Z","dependencies_parsed_at":null,"dependency_job_id":"b01528c1-4eaa-463e-ad30-4437fecde234","html_url":"https://github.com/salrashid123/go_tpm_https_embed","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salrashid123%2Fgo_tpm_https_embed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salrashid123%2Fgo_tpm_https_embed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salrashid123%2Fgo_tpm_https_embed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salrashid123%2Fgo_tpm_https_embed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/salrashid123","download_url":"https://codeload.github.com/salrashid123/go_tpm_https_embed/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225839601,"owners_count":17532308,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["certificate","golang","tls","trusted-computing","trusted-platform-module"],"created_at":"2024-11-22T04:15:17.862Z","updated_at":"2025-07-12T22:32:18.240Z","avatar_url":"https://github.com/salrashid123.png","language":"Go","readme":"### mTLS with TPM bound private key\n\nSimple http client/server in golang where the private key used in the connection is generated and embedded within a [Trusted Platform Module](https://trustedcomputinggroup.org/resource/trusted-platform-module-tpm-summary/).\n\nThe steps here will create a client and server using a local software tpm `swtpm`. On that TPM, create two RSA keys, generate a CSR using those keys, then an external CA will issue an x509 cert using that csr.\n\nFinally, the client will establish an mTLS https connection to the server\n\n---\n\n* If you want to see one-way TLS where the server's private key is embedded in a TPM and the private key is cryptographically verified (tpm remote attestation), please instead see [https://github.com/salrashid123/tls_ak](https://github.com/salrashid123/tls_ak)\n\nfor python, see [Python mTLS client/server with TPM based key](https://gist.github.com/salrashid123/4cb714d800c9e8777dfbcd93ff076100)\n\n---\n\n\u003e\u003e NOTE: this repo is not supported by Google\n\nTo use this sample, you'll need:\n\n* golang\n* `tpm2_tools`\n* openssl3 (with [tpm2-openssl](https://github.com/tpm2-software/tpm2-openssl))\n* software tpm ([swtpm](https://github.com/stefanberger/swtpm))\n\nThe TPM based private keys conforms to [ASN.1 Specification for TPM 2.0 Key Files](https://www.hansenpartnership.com/draft-bottomley-tpm2-keys.html) which in its basic mode is compatible with openssl\n\n### QuickStart\n\nif you want to use the keys provided in this repo, you just need `swtpm`\n\n#### Start swtpm\n\nStart two software TPMs on different ports to simulate the client and server's TPMs\n\n```bash\ncd certs/\n## tpm for server\nswtpm socket --tpmstate dir=myvtpm --tpm2 --server type=tcp,port=2321 --ctrl type=tcp,port=2322 --flags not-need-init,startup-clear --log level=2\n\n## in a new window, start tpm for the client\nswtpm socket --tpmstate dir=myvtpm2 --tpm2 --server type=tcp,port=2341 --ctrl type=tcp,port=2342 --flags not-need-init,startup-clear --log level=2\n```\n\n##### Start Server\n\nTo start the server using the built in demo `swtpm`\n```bash\ngo run src/server/server.go -cacert certs/ca/root-ca.crt \\\n   -servercert certs/server.crt \\\n    --severkey=certs/server_key.pem -port :8081 \\\n      --tpm-path=\"127.0.0.1:2321\"\n```\n\nYou can test the config locally using the pre-generated client certificates provided in this repo\n\n(the following uses curl and ordinary (non-tpm) client certifcates)\n\n```bash\ncurl -v -H \"Host: server.domain.com\"  --resolve  server.domain.com:8081:127.0.0.1 \\\n   --cert certs/user10.crt --key certs/user10.key \\\n    --cacert certs/ca/root-ca.crt https://server.domain.com:8081/index.html\n```\n\n##### Start Client\n\nRun the client which uses TPM-based client certificates,  in a new window:\n\n```bash\ngo run src/client/client.go -cacert certs/ca/root-ca.crt \\\n  --clientkey=certs/client_key.pem --pubCert=certs/client.crt  \\\n   --address localhost --tpm-path=\"127.0.0.1:2341\"\n```\n\nWHat this shows is mTLS where both ends have the TLS private key on the TPM.\n\n---\n\n### Appendix\n\nThe following sets up your own certs and software or real TPMs.\n\nIf you want to use a real TPM, you need openssl tpm support but you don't need to export the `TPM2*`  environment variables.  For a real tpm, you'll also need to speicfy `--tpm-path=/dev/tpmrm0`\n\n####  Server\n\nThe following will setup a server cert where the private key is on a TPM.  For this you need to install openssl tpm support and `tpm2_tools`\n\nif you'd rather use a real tpm than a sotware one, dont' export the TPM* env variables or start the swtpms.\n\nFinally, while running the client or server set `--tpm-path=\"/dev/tpmrm0\"`\n\n\nFor a swtpm:\n\n```bash\nmkdir myvtpm\nsudo swtpm_setup --tpmstate myvtpm --tpm2 --create-ek-cert\nsudo swtpm socket --tpmstate dir=myvtpm --tpm2 --server type=tcp,port=2321 --ctrl type=tcp,port=2322 --flags not-need-init,startup-clear --log level=2\n\nexport TPM2TOOLS_TCTI=\"swtpm:port=2321\"\nexport TPM2OPENSSL_TCTI=\"swtpm:port=2321\"\nexport TPM2TSSENGINE_TCTI=\"swtpm:port=2321\"\nexport OPENSSL_MODULES=/usr/lib/x86_64-linux-gnu/ossl-modules/\ntpm2_flushcontext -t \u0026\u0026 tpm2_flushcontext -s \u0026\u0026 tpm2_flushcontext -l\n# export TSS2_LOG=esys+debug\n\n\n### first verify you have openssl installed and configured for TPM:\nopenssl list  -provider tpm2  -provider default  --providers\n\n  Providers:\n    default\n      name: OpenSSL Default Provider\n      version: 3.5.0\n      status: active\n    tpm2\n      name: TPM 2.0 Provider\n      version: 1.3.0\n      status: active\n\ncd certs/\nprintf '\\x00\\x00' \u003e unique.dat\ntpm2_createprimary -C o -G ecc -g sha256  -c rprimary.ctx -a \"fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda|restricted|decrypt\" -u unique.dat\n\ntpm2_create -G rsa2048:rsapss:null -g sha256 -u server.pub -r server.priv -C rprimary.ctx\ntpm2_flushcontext -t \u0026\u0026 tpm2_flushcontext -s \u0026\u0026 tpm2_flushcontext -l\n# tpm2_load -C rprimary.ctx -u server.pub -r server.priv -c server.ctx\n\n## convert rkey.pub rkey.priv to PEM format\n## note, you may need to add a -p parameter to tpm2_encodeobject if the version of tpm2_tools does not include (https://github.com/tpm2-software/tpm2-tools/issues/3458)\ntpm2_encodeobject -C rprimary.ctx -u server.pub -r server.priv -o server_key.pem\n\n### you'll know if you need to if you run the following and it prompts for a password\nopenssl rsa -provider tpm2  -provider default -in server_key.pem --text\n\nexport SAN=\"DNS:server.domain.com\"\nopenssl req -new  -provider tpm2  -provider default    -config server.conf \\\n  -out server.csr  \\\n  -key server_key.pem  -reqexts server_reqext   \\\n  -subj \"/C=US/O=Google/OU=Enterprise/CN=server.domain.com\" \n\nopenssl req -in server.csr -noout -text\n\nopenssl ca \\\n    -config single-root-ca.conf \\\n    -in server.csr \\\n    -out server.crt  \\\n    -extensions server_ext\n\n# run the server as go\ngo run src/server/server.go -cacert certs/ca/root-ca.crt \\\n   -servercert certs/server.crt \\\n    --severkey=certs/server_key.pem -port :8081 \\\n      --tpm-path=\"127.0.0.1:2321\"\n```\n\n\n#### Client\n\nFor the client,\n\n```bash\nmkdir myvtpm2\nsudo swtpm_setup --tpmstate myvtpm2 --tpm2 --create-ek-cert\nsudo swtpm socket --tpmstate dir=myvtpm2 --tpm2 --server type=tcp,port=2341 --ctrl type=tcp,port=2342 --flags not-need-init,startup-clear --log level=2\n\nexport TPM2TOOLS_TCTI=\"swtpm:port=2341\"\nexport TPM2OPENSSL_TCTI=\"swtpm:port=2341\"\nexport TPM2TSSENGINE_TCTI=\"swtpm:port=2341\"\nexport OPENSSL_MODULES=/usr/lib/x86_64-linux-gnu/ossl-modules/\ntpm2_flushcontext -t \u0026\u0026 tpm2_flushcontext -s \u0026\u0026 tpm2_flushcontext -l\n\nprintf '\\x00\\x00' \u003e unique.dat\ntpm2_createprimary -C o -G ecc -g sha256  -c rcprimary.ctx -a \"fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda|restricted|decrypt\" -u unique.dat\n\ntpm2_create -G rsa2048:rsapss:null -g sha256 -u client.pub -r client.priv -C rcprimary.ctx\ntpm2_load -C rcprimary.ctx -u client.pub -r client.priv -c client.ctx\n\n## note, you may need to add a -p parameter to tpm2_encodeobject (https://github.com/tpm2-software/tpm2-tools/issues/3458)\ntpm2_encodeobject -C rcprimary.ctx -u client.pub -r client.priv -o client_key.pem\n\n# create a csr using the tpm key...i have it in this repo:\nopenssl rsa -provider tpm2  -provider default -in client_key.pem --text\n\nexport SAN=\"DNS:client.domain.com\"\nopenssl req -new  -provider tpm2  -provider default    -config client.conf \\\n  -out client.csr  \\\n  -key client_key.pem  -reqexts client_reqext   \\\n  -subj \"/C=US/O=Google/OU=Enterprise/CN=client.domain.com\" \n\nopenssl req -in client.csr -noout -text\n\nopenssl ca \\\n    -config single-root-ca.conf \\\n    -in client.csr \\\n    -out client.crt  \\\n    -extensions client_ext\n\ngo run src/client/client.go -cacert certs/ca/root-ca.crt \\\n  --clientkey=certs/client_key.pem --pubCert=certs/client.crt  \\\n   --address localhost --tpm-path=\"127.0.0.1:2341\"\n```\n\nAt this point, you should see a simple 'ok' from the sever\n\n#### Openssl\n\nIf you would rather test the client/server using openssl\n\n```bash\nswtpm socket --tpmstate dir=myvtpm --tpm2 --server type=tcp,port=2321 --ctrl type=tcp,port=2322 --flags not-need-init,startup-clear --log level=2\n\nexport TPM2TOOLS_TCTI=\"swtpm:port=2321\"\nexport TPM2OPENSSL_TCTI=\"swtpm:port=2321\"\nexport TPM2TSSENGINE_TCTI=\"swtpm:port=2321\"\nexport OPENSSL_MODULES=/usr/lib/x86_64-linux-gnu/ossl-modules/\ntpm2_flushcontext -t \u0026\u0026 tpm2_flushcontext -s \u0026\u0026 tpm2_flushcontext -l\n\nopenssl s_server  -provider tpm2  -provider default  \\\n        -cert server.crt \\\n      -key server_key.pem \\\n      -port 8081 \\\n      -CAfile ca/root-ca.crt \\\n      -tlsextdebug \\\n      -tls1_3  \\\n      -trace \\\n      -WWW\n```\n\n```bash\nswtpm socket --tpmstate dir=myvtpm2 --tpm2 --server type=tcp,port=2341 --ctrl type=tcp,port=2342 --flags not-need-init,startup-clear --log level=2\n\nexport TPM2TOOLS_TCTI=\"swtpm:port=2341\"\nexport TPM2OPENSSL_TCTI=\"swtpm:port=2341\"\nexport TPM2TSSENGINE_TCTI=\"swtpm:port=2341\"\nexport OPENSSL_MODULES=/usr/lib/x86_64-linux-gnu/ossl-modules/\ntpm2_flushcontext -t \u0026\u0026 tpm2_flushcontext -s \u0026\u0026 tpm2_flushcontext -l\n\n## in new window\ngo run src/client/client.go -cacert certs/ca/root-ca.crt \\\n  --clientkey=certs/client_key.pem --pubCert=certs/client.crt  \\\n   --address localhost --tpm-path=\"127.0.0.1:2341\"\n```\n\n### References\n\nOther references:\n\n- [Trusted Platform Module (TPM) and Google Cloud KMS based mTLS auth to HashiCorp Vault](https://github.com/salrashid123/vault_mtls_tpm)\n- TPM TLS with nginx, openssl:  [https://github.com/salrashid123/go_tpm_https#nginx](https://github.com/salrashid123/go_tpm_https#nginx)]\n\nRSA-PSS padding:\n- [Synthesized PSS support](https://github.com/tpm2-software/tpm2-pkcs11/issues/417)\n- [PSS advertising during TLS handshake for TPM signing ](https://chromium-review.googlesource.com/c/chromium/src/+/2984231)\n- [TLS salt length auto detection, switch from DIGEST to AUTO](http://openssl.6102.n7.nabble.com/RFC-TLS-salt-length-auto-detection-switch-from-DIGEST-to-AUTO-td78057.html)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsalrashid123%2Fgo_tpm_https_embed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsalrashid123%2Fgo_tpm_https_embed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsalrashid123%2Fgo_tpm_https_embed/lists"}