Skip to content

Utility for flushing active TPM handles. #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jan 30, 2019

Conversation

sambdavidson
Copy link
Contributor

Reads all active handles through a call to the TPM rw:

... := tpm2.GetCapability(rw, tpm2.CapabilityHandles, ^uint32(0), 0x80000000)

Then flushes those handles with tpm2.FlushContext(...).

I am not 100% certain on the magic const 0x80000000 used in GetCapability but it appears to work correctly. I found it here: https://github.com/google/go-tpm/blob/master/tpm2/tpm2_test.go#L135

…ll active handles and flush them from the TPM
@awly
Copy link

awly commented Jan 18, 2019

Move the files to a separate directory under github.com/google/go-tpm-tools/cmd and make it package main. This is mostly useful as a standalone binary.

@awly
Copy link

awly commented Jan 18, 2019

0x80000000 is property parameter of the TPM2_GetCapability call.
For handles it defines which type of handle to return. The type of the handle (using TPM_HT_... constants) is placed in most significant octet of the property.
In this case it's TPM_HT_TRANSIENT.

The code should make it more obvious instead of using an opaque constant.

Copy link
Member

@josephlr josephlr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @samdamana for the PR!

Overall, this is good functionality that we want to add to go-tpm-tools. However, we want to make sure the facilities are sufficiently clean and general. See my comments below:

// FlushActiveHandles calls FlushContext() on all active handles within the
// TPM at io.ReadWriter rw. Returns nil if successful or TPM has no active
// handles.
func FlushActiveHandles(rw io.ReadWriter) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @awly said, flushing all transient handles is best put in as a standalone binary. The function to list all handles of a specific type; however, should be a library function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

josephlr pushed a commit that referenced this pull request Jan 25, 2019
* Implement LoadExternal

Add integration test, without loading private key

* Implement Certify

This does not work yet! Committing to keep the changes, for some other
work.

* Refactor encodePasswordAuthArea

Use correct size of inputs, support multiple password sessions.

* Make Certify work

Fix CreatePrimary with signing keys
Fix LoadExternal with private key
Fix integration test for certifying a TPM key
Add integration test for certifying externally-loaded key

* Unify TPM2B_PUBLIC parsing and check Certify signatures

Also add handling for default RSA key exponent returned from TPM.

* Add doc comment to Certify

* Address review comments

- Fix grammar
- Add comment about big.Int and TPM endianness
- Add a const for empty passwords in tests
- Increase RSA key size
- Extract anonymous struct in Certify into named one

* Add README with instructions on running tests

* Merge an if statement
@sambdavidson
Copy link
Contributor Author

Ready for another look.

for _, handleType := range handleTypes {
err = flushHandlesOfType(rw, handleType)
if err != nil {
log.Fatalf("%v", err)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log.Fatal will prevent any deferred calls. Move OpenTPM + this loop to another func that returns an error. That way deferred rw.Close can run before log.Fatal

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

}
handles := make([]tpmutil.Handle, len(vals))
for i, v := range vals {
handles[i] = v.(tpmutil.Handle)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a checked assertion here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor Author

@sambdavidson sambdavidson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the code to address your feedback.

for _, handleType := range handleTypes {
err = flushHandlesOfType(rw, handleType)
if err != nil {
log.Fatalf("%v", err)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

}
handles := make([]tpmutil.Handle, len(vals))
for i, v := range vals {
handles[i] = v.(tpmutil.Handle)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor Author

@sambdavidson sambdavidson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your suggestions have been implemented.

{false, false, false, true, []tpm2.HandleType{tpm2.HandleTypeTransient, tpm2.HandleTypeLoadedSession, tpm2.HandleTypeSavedSession}},
} {
// Overwrite flag pointer values.
flushTransient = &test.flushTransientFlag
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TL;DR: avoid global state (including flags) whenever possible.

Generally speaking, tests shouldn't know about flags at all (unless you test flag parsing).
Flags are func main-level concern and all other code should get configuration passed explicitly through func arguments or struct fields.
Looking outside of their context into the global vars (which get set through flags at runtime) makes testing harder: you can't parallelize tests that read flags due to memory safety, you must remember to clean up modified values to make tests order-independent.

However, this program is not production-critical so we don't need to be so strict about code structure or testing.

t.Fatal(err)
}
if len(h) != 0 {
t.Fatalf("Simulator should be empty of transient handles; got: %d", len(h))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put "got" before "want" in message

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed I think?

Copy link
Contributor Author

@sambdavidson sambdavidson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@awly 's suggestions have been implemented.

t.Fatal(err)
}
if len(h) != 0 {
t.Fatalf("Simulator should be empty of transient handles; got: %d", len(h))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed I think?

Copy link
Contributor Author

@sambdavidson sambdavidson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of @josephlr 's suggestions and changes have been implemented. Sorry this is my first Github PR. I am just learning how to do these sub-review things.

// FlushActiveHandles calls FlushContext() on all active handles within the
// TPM at io.ReadWriter rw. Returns nil if successful or TPM has no active
// handles.
func FlushActiveHandles(rw io.ReadWriter) error {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

}
defer simulator.Close()

// Loads then flushes 1, 2, ...maxHandles handles.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It only loads in transient handles. I kind of like looping load then flush. It helped me identify bugs in the past where I returned incorrect numbers of handles.

@awly
Copy link

awly commented Jan 29, 2019

LGTM, leaving this up to @josephlr

public := tpm2.Public{
Type: tpm2.AlgRSA,
NameAlg: tpm2.AlgSHA1,
Attributes: tpm2.FlagSign | tpm2.FlagSensitiveDataOrigin | tpm2.FlagUserWithAuth,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SensitiveDataOrigin doesn't make sense in this context. I'm disappointed if this is not an error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its not haha. But removed.

Copy link
Member

@josephlr josephlr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samdamana This code looks great, the only remaining things are organisational, mainly just to use the internal package.

Copy link
Member

@josephlr josephlr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks again!!

@josephlr josephlr merged commit f38bf7b into google:master Jan 30, 2019
josephlr pushed a commit to josephlr/go-tpm-tools that referenced this pull request Jul 3, 2019
Implement autotools build for TPM and Platform code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants