Giter Club home page Giter Club logo

spire-tpm-plugin's Introduction

SPIRE TPM Plugin

This repository contains agent and server plugins for SPIRE to allow TPM 2-based node attestation.

Menu

Demo

Here's a quick demo that shows how this plugin looks when run:

asciicast

Quick Start

Before starting, create a running SPIRE deployment and add the following configuration to the agent and server:

Agent Configuration

NodeAttestor "tpm" {
	plugin_cmd = "/path/to/plugin_cmd"
	plugin_checksum = "sha256 of the plugin binary"
	plugin_data {
	}
}

Server Configuration

NodeAttestor "tpm" {
	plugin_cmd = "/path/to/plugin_cmd"
	plugin_checksum = "sha256 of the plugin binary"
	plugin_data {
		ca_path = "/opt/spire/.data/certs"
		hash_path = "/opt/spire/.data/hashes"
	}
}
key type required description default
ca_path string the path to the CA directory /opt/spire/.data/certs
hash_path string the path to the Hash directory /opt/spire/.data/hashes

Directory Configuration

For this plugin to work, either ca_path, hash_path, or both must be configured.

Certificate Directory

Contains the manufacturer CA cert that signed the TPM's EK certificate in PEM or DER format. Drop all manufacturer CA certs in the directory ca_path.

Note: not all TPM's have an EK certificate, if yours does not then use hash_path

Hash Directory

Contains empty files named after the EK public key hash. Use the get_tpm_pubhash command to print out the TPM's EK public key hash. Example:

agent  $ ./get_tpm_pubhash
1b5bbe2e96054f7bc34ebe7ba9a4a9eac5611c6879285ceff6094fa556af485c 

server $ mkdir -p /opt/spire/.data/hashes
server $ touch /opt/spire/.data/hashes/1b5bbe2e96054f7bc34ebe7ba9a4a9eac5611c6879285ceff6094fa556af485c

How it Works

The plugin uses TPM credential activation as the method of attestation. The plugin operates as follows:

  1. Agent generates AK (attestation key) using TPM
  2. Agent sends the AK attestation parameters and EK certificate or public key to the server
  3. Server inspects EK certificate or public key
    1. If hash_path exists, and the public key hash matches filename in hash_path, validation passes
    2. If ca_path exists, and the EK certificate was signed by any chain in ca_path, validation passes
  4. If validation passed, the server generates a credential activation challenge using
    1. The EK public key
    2. The AK attestation parameters
  5. Server sends challenge to agent
  6. Agent decrypts the challenge's secret
  7. Agent sends back decrypted secret
  8. Server verifies that the decrypted secret is the same it used to build the challenge
  9. Server creates a SPIFFE ID in the form of spiffe://<trust_domain>/agent/tpm/<sha256sum_of_tpm_pubkey>
  10. All done!

For info on how TPM attestation usually works and how this implementation differs, visit TPM.md.

Building

To build this plugin on Linux, run make build. Because of the dependency on go-attestation, you must have libtspi-dev installed.

Contributions

We ❤️ contributions.

Have you had a good experience with this project? Why not share some love and contribute code, or just let us know about any issues you had with it?

We welcome issue reports here; be sure to choose the proper issue template for your issue, so that we can be sure you're providing the necessary information.

Before sending a Pull Request, please make sure you read our Contribution Guidelines.

License

Please read the LICENSE file.

Code of Conduct

This project has adopted a Code of Conduct. If you have any concerns about the Code, or behavior which you have experienced in the project, please contact us at [email protected].

Security Vulnerability Reporting

If you believe you have identified a security vulnerability in this project, please send email to the project team at [email protected], detailing the suspected issue and any methods you've found to reproduce it.

Please do NOT open an issue in the GitHub repository, as we'd prefer to keep vulnerability reports private until we've had an opportunity to review and address them.

spire-tpm-plugin's People

Contributors

caleblloyd avatar dennisgove avatar kpfleming avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spire-tpm-plugin's Issues

Abandoned project

It seems this one doesn't work with latest (v1.0+) SPIRE versions and according to repo activity - project is abandoned.

Use hex-encoded Public Key Hash instead of Base64 to avoid / char in SPIFFE-ID

SPIFFE-ID paths may be hierarchial, and using the base64 encoded Public Key Hash results in SVIDs that look like:

spiffe://domain.test/spire/agent/tpm/c1XbxrikL+sgdCw7hKFlmh2/y/QenHiIfLazBlsG/yQ=

This appears as if the path is hierarchial, since base64 includes / in it's character set

Additionally, #4 proposes storing authorized Public Key Hashses as an empty file on the filesystem. Since / is a directory separator on Linux, it cannot be represented in a file

Hex encoding for SHA256 representations is fairly standard practice, and would alleviate these issues

Add note about not supporting plugin SDK / newer Spire versions

Since SPIRE v1.1.0, SPIRE no longer supports plugins that don't use the plugin SDK. That includes the SPIRE TPM plugin in this repository. Unfortunately, newer SPIRE versions seem to produce confusing and unhelpful error messages (a piece of which is shown below) when one attempts to use a plugin that doesn't use the plugin SDK.

err="rpc error: code = Unimplemented desc = unknown service plugin.GRPCStdio" external=true plugin_name=tpm plugin_type=NodeAttestor subsystem_name=tpm.stdio site:github.com

Due to this, I feel it would be helpful to those seeking to use this plugin if at least one of the following were done:

  1. Add a note to the README saying that the plugin does not use the plugin SDK and thus will not work with SPIRE versions v1.1.0 or later.
  2. Add a note to the README mentioning the fork here, since that fork does use the plugin SDK.

node reimaging question

This is more of a question then an issue. The documentation is a bit unclear on this point. If the node is totally reinstalled, will it end up using the same AK or generate a new one? Would the SVID change in this case? If reimaged too frequently would the keys waste too much space in the TPM and cause attestation to fail?

Using Simulated TPM for node attestation

Not a feature request, but more of a question at this point.

Is your feature request related to a problem? Please describe.
I see references to the MS TPM 2.0 simulator in the pkg/ dir and ci/ dir.
I'm trying to see if I can hook up this plugin to the MS TPM 2.0 simulator running on my machine at the default port.

Describe the solution you'd like
Is there already a way to connect to the TPM simulator on TCP port? If so, a "help" guide would be great.

x509 Certificate type mismatch causing build to fail

Describe the bug

x509 Certificate type mismatch causing build to fail in Go 1.14.2

To Reproduce
Steps to reproduce the behavior:

  1. Use Go 1.14.2
  2. Run make
  3. Error:
cmd/server/tpm_attestor/tpm_attestor.go:170:39: 
cannot use leaf (type *"crypto/x509".Certificate) 
as type 
*"github.com/google/certificate-transparency-go/x509".Certificate 
in argument to 
"github.com/bloomberg/spire-tpm-plugin/pkg/common".GetPubHash

Expected behavior

Builds properly

Screenshot

Screenshot from 2020-04-28 16-00-05

Environment (please complete the following information):

  • Ubuntu 20.04
  • Go 1.14.2
  • libtspi-dev for trousers

Trust based on EKPub

Describe the solution you'd like

Currently, EKCert chain must be validated and a node is allowed. This requires the server to have CA roots for each TPM manufacturer, and trusts all devices with a matching CA root.

I think it would also be beneficial to allow for a list of EKPub hashes to be considered. This would mean trust could be locked down to only certain devices that are on the EKPub whitelist

One solution would be an optional server configuration, such as:

ek_pub_hash_path  = "/opt/spire/.data/ek_pub_hashes"

Each file in that directory would be an empty file with a filename being a SHA-256 hash of an authorized EK Pub. If ek_pub_hash_path is supplied, a check for file exists on {ek_pub_hash_path}/{ek_pub_hash} would be performed and if found, considered valid.

Describe alternatives you've considered

Considered a datastore API for checking EK Pubs that reside in a remote datastore, but that would introduce additional complexity into this project, and could be handled out-of-band.

Additional context

The solution would be similar to the "Trust based on EKPub" described here: https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/manage/component-updates/tpm-key-attestation#BKMK_DeploymentOverview

Could not verify cert: Unhandled Critical Extension

Describe the bug
TPM node attestation fails with error: "tpm: could not verify cert: x509: unhandled critical extension (2.5.29.17)"

To Reproduce
Steps to reproduce the behavior:

  1. Create EK and CA certs with swtpm
  2. Launch QEMU with emulated swtpm
  3. Copy root CA cert to default location "/opt/spire/.data/certs"
  4. Run spire-server with config file supporting TPM plugin
  5. Run spire-agent with config file supporting TPM plugin
  6. See error

Expected behavior
Expected to get a successful node attestion, as in demo.

Environment (please complete the following information):

  • Operating System and Version: Debian 10 in QEMU 5.0 VM
  • Spire 0.10.1 release

Additional context

  • The OID 2.5.29.17 extension corresponds to "Subject Alternative Name". This extension is not present in the certificate, and the Subject field in the certificate is not empty, so should not be critical.
  • Same error is given when no certs are populated in certs folder
  • Here is the self-signed root CA cert:

Certificate:
Data:
Version: 3 (0x2)
Serial Number:
56:34:5b:ff:d9:3e:d3:c0:11:17:73:9a:96:a3:44:31:05:fe:5a:66
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN = swtpm-localca-rootca
Validity
Not Before: Jun 22 19:05:24 2020 GMT
Not After : Jun 20 19:05:24 2030 GMT
Subject: CN = swtpm-localca-rootca
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (3072 bit)
Modulus:
00:cb:89:df:4d:0f:be:b7:76:31:bf:1c:94:17:64:
3f:df:ee:f8:6a:90:df:6c:a6:3c:2c:b6:b6:fa:e7:
b1:96:97:94:a2:19:30:b9:ee:8d:ab:df:05:2d:32:
c5:6b:15:25:dd:ba:b1:78:90:b0:12:82:0e:6b:4f:
2f:49:3a:8c:fa:0c:aa:cc:43:01:5b:37:f4:e4:f0:
e7:9d:84:89:10:bd:fe:d4:2c:a3:1f:3b:71:42:e4:
fc:6c:11:8f:a1:f8:42:22:9c:ec:81:d5:ab:45:d4:
44:96:81:de:76:1d:73:52:36:df:b2:ea:15:a0:d7:
20:43:c5:90:83:38:86:bb:e8:20:43:41:ef:17:74:
6b:c1:3d:24:ce:90:a9:17:10:d6:d5:c3:17:2f:9b:
35:5c:cf:00:fb:90:80:fb:d8:27:1c:af:69:82:7d:
99:dd:7f:a3:96:20:45:c2:18:0d:3e:06:5b:0a:8f:
1d:36:12:9a:6b:93:f2:25:59:64:f2:c1:cc:4b:e3:
06:24:aa:dc:88:04:e4:c0:8b:1c:68:91:14:bf:ed:
20:4c:47:d6:aa:3a:38:f2:53:13:2e:8e:45:17:66:
18:51:2f:4d:fa:5a:0c:63:4c:ec:fc:15:08:3e:77:
bf:8a:41:30:0c:b6:d1:6f:c2:3f:d9:2d:48:d1:86:
c4:33:55:54:e8:28:3c:9f:55:70:aa:9d:3c:d5:4f:
9f:74:27:bc:cd:fe:e4:f6:87:08:28:fa:91:63:e9:
3a:77:c4:34:75:88:83:3b:20:ca:e6:f3:4d:6d:01:
54:34:f5:7d:35:2e:24:c7:75:b9:b0:30:8b:5d:c9:
55:86:98:dd:b5:84:d3:3f:c3:76:cc:ec:b7:87:2a:
7f:54:ee:d7:7a:38:40:e6:1b:1e:05:14:f2:b3:87:
9b:b9:ee:21:1c:34:a2:17:72:2b:ed:cb:d4:88:de:
ec:04:c4:e1:4c:5a:9e:94:8e:a5:0a:b6:48:ce:8a:
2a:62:94:ee:98:6c:25:e7:01:b3
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Key Usage: critical
Certificate Sign
X509v3 Subject Key Identifier:
85:A5:B9:F8:00:7F:22:8B:87:02:8B:D7:58:E1:EF:40:B0:0B:ED:B4
Signature Algorithm: sha256WithRSAEncryption
3e:a6:f9:31:9f:59:e8:cb:0d:e0:2e:e1:5a:29:58:e3:02:cc:
2d:8e:d2:c9:7d:e8:75:65:eb:5a:47:31:74:f5:2f:08:81:72:
3e:33:ef:3e:38:0e:64:36:a7:8f:85:49:45:cb:69:a9:84:12:
cd:84:b5:c8:b3:ed:b6:f5:10:09:0b:3f:76:53:18:a1:8d:74:
38:80:c8:1e:e1:16:27:23:eb:c9:b5:a2:75:27:b2:0a:da:9d:
a4:af:59:23:21:f1:f6:32:65:a8:79:03:ff:2f:84:43:cb:a0:
06:65:cb:2b:8a:f7:6a:47:0a:a5:75:31:d9:6b:c6:9c:f5:c9:
19:f7:57:c5:e3:0d:61:ef:4c:2f:7b:30:c0:02:79:93:11:73:
75:09:6f:f4:63:58:53:12:f1:23:34:1f:27:25:a7:19:c8:42:
42:f2:a9:07:6c:0b:f5:6a:42:aa:b6:95:87:45:4e:5c:69:11:
db:35:6c:8f:fb:95:2b:52:4a:51:42:e2:ec:f2:34:22:b8:61:
fb:35:89:69:97:fd:03:45:ac:0d:01:da:d5:3c:f9:15:2e:af:
4d:60:35:1a:a4:0e:6f:a5:1a:1d:b7:b8:c0:24:df:86:76:39:
04:16:a9:a5:f3:00:7d:dd:ad:94:c2:b4:76:7a:fb:48:a9:ec:
bb:d0:f5:3f:23:11:17:5f:e2:97:e9:2f:64:ee:d4:d8:a6:50:
58:71:21:4b:8f:b3:0f:ae:62:91:86:ce:a0:ff:42:6b:97:f9:
fb:cd:11:24:28:2c:ee:1a:38:ca:86:bc:99:c0:ef:f6:50:b3:
b1:cd:b2:a6:3b:f7:cf:90:00:df:19:a3:78:7e:9b:23:d9:18:
02:68:1a:72:86:3e:c0:b7:ad:3c:25:4e:bd:df:6a:44:0d:48:
63:f1:b5:85:06:91:56:6f:e1:d2:f8:46:33:ca:fb:e4:44:b8:
19:66:97:7b:60:4e:17:09:d0:27:22:dd:d8:1a:4b:77:5c:f2:
dd:7f:75:e9:a4:6d
-----BEGIN CERTIFICATE-----
MIIEDzCCAnegAwIBAgIUVjRb/9k+08ARF3OalqNEMQX+WmYwDQYJKoZIhvcNAQEL
BQAwHzEdMBsGA1UEAxMUc3d0cG0tbG9jYWxjYS1yb290Y2EwHhcNMjAwNjIyMTkw
NTI0WhcNMzAwNjIwMTkwNTI0WjAfMR0wGwYDVQQDExRzd3RwbS1sb2NhbGNhLXJv
b3RjYTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAMuJ300Pvrd2Mb8c
lBdkP9/u+GqQ32ymPCy2tvrnsZaXlKIZMLnujavfBS0yxWsVJd26sXiQsBKCDmtP
L0k6jPoMqsxDAVs39OTw552EiRC9/tQsox87cULk/GwRj6H4QiKc7IHVq0XURJaB
3nYdc1I237LqFaDXIEPFkIM4hrvoIENB7xd0a8E9JM6QqRcQ1tXDFy+bNVzPAPuQ
gPvYJxyvaYJ9md1/o5YgRcIYDT4GWwqPHTYSmmuT8iVZZPLBzEvjBiSq3IgE5MCL
HGiRFL/tIExH1qo6OPJTEy6ORRdmGFEvTfpaDGNM7PwVCD53v4pBMAy20W/CP9kt
SNGGxDNVVOgoPJ9VcKqdPNVPn3QnvM3+5PaHCCj6kWPpOnfENHWIgzsgyubzTW0B
VDT1fTUuJMd1ubAwi13JVYaY3bWE0z/Ddszst4cqf1Tu13o4QOYbHgUU8rOHm7nu
IRw0ohdyK+3L1Ije7ATE4UxanpSOpQq2SM6KKmKU7phsJecBswIDAQABo0MwQTAP
BgNVHRMBAf8EBTADAQH/MA8GA1UdDwEB/wQFAwMHBAAwHQYDVR0OBBYEFIWlufgA
fyKLhwKL11jh70CwC+20MA0GCSqGSIb3DQEBCwUAA4IBgQA+pvkxn1noyw3gLuFa
KVjjAswtjtLJfeh1ZetaRzF09S8IgXI+M+8+OA5kNqePhUlFy2mphBLNhLXIs+22
9RAJCz92UxihjXQ4gMge4RYnI+vJtaJ1J7IK2p2kr1kjIfH2MmWoeQP/L4RDy6AG
ZcsrivdqRwqldTHZa8ac9ckZ91fF4w1h70wvezDAAnmTEXN1CW/0Y1hTEvEjNB8n
JacZyEJC8qkHbAv1akKqtpWHRU5caRHbNWyP+5UrUkpRQuLs8jQiuGH7NYlpl/0D
RawNAdrVPPkVLq9NYDUapA5vpRodt7jAJN+GdjkEFqml8wB93a2UwrR2evtIqey7
0PU/IxEXX+KX6S9k7tTYplBYcSFLj7MPrmKRhs6g/0Jrl/n7zREkKCzuGjjKhryZ
wO/2ULOxzbKmO/fPkADfGaN4fpsj2RgCaBpyhj7At608JU6932pEDUhj8bWFBpFW
b+HS+EYzyvvkRLgZZpd7YE4XCdAnIt3YGkt3XPLdf3XppG0=
-----END CERTIFICATE-----

Thanks for any help!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.