-
Notifications
You must be signed in to change notification settings - Fork 74
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
Conversation
…ll active handles and flush them from the TPM
Move the files to a separate directory under |
The code should make it more obvious instead of using an opaque constant. |
There was a problem hiding this 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:
tpm2tools/flush_active_handles.go
Outdated
// 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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
* 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
…es main under cmd/
…ogle/... Fixed up some comments.
Ready for another look. |
cmd/flush_handles.go
Outdated
for _, handleType := range handleTypes { | ||
err = flushHandlesOfType(rw, handleType) | ||
if err != nil { | ||
log.Fatalf("%v", err) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
tpm2tools/handles.go
Outdated
} | ||
handles := make([]tpmutil.Handle, len(vals)) | ||
for i, v := range vals { | ||
handles[i] = v.(tpmutil.Handle) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this 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.
cmd/flush_handles.go
Outdated
for _, handleType := range handleTypes { | ||
err = flushHandlesOfType(rw, handleType) | ||
if err != nil { | ||
log.Fatalf("%v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
tpm2tools/handles.go
Outdated
} | ||
handles := make([]tpmutil.Handle, len(vals)) | ||
for i, v := range vals { | ||
handles[i] = v.(tpmutil.Handle) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this 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.
cmd/flush_handles_test.go
Outdated
{false, false, false, true, []tpm2.HandleType{tpm2.HandleTypeTransient, tpm2.HandleTypeLoadedSession, tpm2.HandleTypeSavedSession}}, | ||
} { | ||
// Overwrite flag pointer values. | ||
flushTransient = &test.flushTransientFlag |
There was a problem hiding this comment.
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)) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed I think?
There was a problem hiding this 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)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed I think?
There was a problem hiding this 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.
tpm2tools/flush_active_handles.go
Outdated
// 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 { |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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.
LGTM, leaving this up to @josephlr |
public := tpm2.Public{ | ||
Type: tpm2.AlgRSA, | ||
NameAlg: tpm2.AlgSHA1, | ||
Attributes: tpm2.FlagSign | tpm2.FlagSensitiveDataOrigin | tpm2.FlagUserWithAuth, |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks again!!
Implement autotools build for TPM and Platform code
Reads all active handles through a call to the TPM
rw
: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