From ac398b4bd0ae44d01e4c405be649bfa1e11a470e Mon Sep 17 00:00:00 2001 From: Chris Coulson Date: Thu, 18 Apr 2024 22:40:59 +0100 Subject: [PATCH] we can't inherit Dispose calls with go, so work around the composition instead --- command_test.go | 4 +-- mu/mu.go | 7 +---- mu/mu_test.go | 5 +++- resources.go | 72 ++++++++++++++++++++++++++++--------------------- 4 files changed, 48 insertions(+), 40 deletions(-) diff --git a/command_test.go b/command_test.go index 9971661..b2534e7 100644 --- a/command_test.go +++ b/command_test.go @@ -400,14 +400,14 @@ func (s *commandSuite) TestUseResouceContextWithAuthPW(c *C) { h := UseResourceContextWithAuth(resource, nil) c.Check(h, NotNil) c.Check(h.Handle(), Equals, resource) - c.Check(h.Session(), DeepEquals, PwSession()) + c.Check(h.Session().SerializeToBytes(), DeepEquals, PwSession().SerializeToBytes()) } func (s *commandSuite) TestUseResouceContextWithAuthNil(c *C) { h := UseResourceContextWithAuth(nil, nil) c.Check(h, NotNil) c.Check(h.Handle(), DeepEquals, NullResource()) - c.Check(h.Session(), DeepEquals, PwSession()) + c.Check(h.Session().SerializeToBytes(), DeepEquals, PwSession().SerializeToBytes()) } func (s *commandSuite) TestCommandContextAddHandles(c *C) { diff --git a/mu/mu.go b/mu/mu.go index 8da1937..5423189 100644 --- a/mu/mu.go +++ b/mu/mu.go @@ -439,12 +439,7 @@ func tpmKind(t reflect.Type, o *options) (TPMKind, error) { k := TPMKindStruct for i := 0; i < t.NumField(); i++ { - f := t.Field(i) - if f.PkgPath != "" { - // structs with unexported fields are unsupported - return TPMKindUnsupported, errors.New("struct type with unexported fields") - } - if isUnion(f.Type) { + if isUnion(t.Field(i).Type) { k = TPMKindTaggedUnion break } diff --git a/mu/mu_test.go b/mu/mu_test.go index 7208153..b6acc01 100644 --- a/mu/mu_test.go +++ b/mu/mu_test.go @@ -992,7 +992,10 @@ func (s *muSuite) TestUnmarshalToNilPointer(c *C) { func (s *muSuite) TestMarshalSizedAndRaw(c *C) { a := Sized(Raw([]byte{})) - c.Check(func() { MarshalToBytes(a) }, PanicMatches, "cannot marshal unsupported type mu.wrappedValue \\(struct type with unexported fields\\)") + c.Check(func() { MarshalToBytes(a) }, PanicMatches, "cannot marshal unsupported type interface {} \\(unsupported kind: interface\\)\n\n"+ + "=== BEGIN STACK ===\n"+ + "... mu.wrappedValue field value\n"+ + "=== END STACK ===\n") c.Check(IsValid(a), internal_testutil.IsFalse) } diff --git a/resources.go b/resources.go index 23d4f04..2208ca8 100644 --- a/resources.go +++ b/resources.go @@ -187,6 +187,22 @@ type handleContext struct { HandleHandle Handle HandleName Name Data *handleContextU + disposeFns []func() `tpm2:"ignore"` +} + +func newHandleContext(handle Handle) HandleContext { + switch handle.Type() { + case HandleTypePCR, HandleTypeNVIndex, HandleTypeHMACSession, HandleTypePolicySession, HandleTypePermanent, HandleTypeTransient, HandleTypePersistent: + out := &handleContext{ + HandleType: handleContextTypeLimited, + HandleHandle: handle, + HandleName: mu.MustMarshalToBytes(handle), + } + out.disposeFns = []func(){out.dispose} + return out + default: + panic("invalid handle type") + } } var _ HandleContext = (*handleContext)(nil) @@ -216,13 +232,19 @@ func (h *handleContext) SerializeToWriter(w io.Writer) error { return err } -func (h *handleContext) Dispose() { +func (h *handleContext) dispose() { h.HandleType = handleContextTypeDisposed h.HandleHandle = HandleUnassigned h.HandleName = MakeHandleName(HandleUnassigned) h.Data = new(handleContextU) } +func (h *handleContext) Dispose() { + for _, fn := range h.disposeFns { + fn() + } +} + func (h *handleContext) checkValid() error { switch h.HandleType { case handleContextTypePermanent: @@ -333,50 +355,38 @@ func (h *handleContext) checkValid() error { return nil } -func newHandleContext(handle Handle) HandleContext { - switch handle.Type() { - case HandleTypePCR, HandleTypeNVIndex, HandleTypeHMACSession, HandleTypePolicySession, HandleTypePermanent, HandleTypeTransient, HandleTypePersistent: - return &handleContext{ - HandleType: handleContextTypeLimited, - HandleHandle: handle, - HandleName: mu.MustMarshalToBytes(handle), - } - default: - panic("invalid handle type") - } -} - type resourceContext struct { handleContext - authValue []byte + authValue []byte `tpm2:"ignore"` } func newResourceContext(handle Handle, name Name) ResourceContext { switch handle.Type() { case HandleTypePCR, HandleTypeNVIndex, HandleTypePermanent, HandleTypeTransient, HandleTypePersistent: - return &resourceContext{ + out := &resourceContext{ handleContext: handleContext{ HandleType: handleContextTypeLimitedResource, HandleHandle: handle, HandleName: name, }, } + out.disposeFns = []func(){out.handleContext.dispose, out.dispose} + return out default: panic("invalid handle type") } } +func (r *resourceContext) dispose() { + r.authValue = nil +} + var _ ResourceContext = (*resourceContext)(nil) func (r *resourceContext) SetAuthValue(authValue []byte) { r.authValue = authValue } -func (r *resourceContext) Dispose() { - r.authValue = nil - r.handleContext.Dispose() -} - func (r *resourceContext) AuthValue() []byte { return bytes.TrimRight(r.authValue, "\x00") } @@ -404,8 +414,6 @@ func newPermanentContext(handle Handle) *permanentContext { var _ ResourceContext = (*permanentContext)(nil) -func (r *permanentContext) Dispose() {} - func nullResource() ResourceContext { return newPermanentContext(HandleNull) } @@ -420,7 +428,7 @@ func newObjectContext(handle Handle, name Name, public *Public) *objectContext { if public == nil { panic("nil public area") } - return &objectContext{ + out := &objectContext{ resourceContext: resourceContext{ handleContext: handleContext{ HandleType: handleContextTypeObject, @@ -430,6 +438,8 @@ func newObjectContext(handle Handle, name Name, public *Public) *objectContext { }, }, } + out.disposeFns = []func(){out.handleContext.dispose, out.dispose} + return out default: panic("invalid handle type") } @@ -463,7 +473,7 @@ func newNVIndexContext(handle Handle, name Name, public *NVPublic) *nvIndexConte if public == nil { panic("nil public area") } - return &nvIndexContext{ + out := &nvIndexContext{ resourceContext: resourceContext{ handleContext: handleContext{ HandleType: handleContextTypeNVIndex, @@ -473,6 +483,8 @@ func newNVIndexContext(handle Handle, name Name, public *NVPublic) *nvIndexConte }, }, } + out.disposeFns = []func(){out.handleContext.dispose, out.dispose} + return out default: panic("invalid handle type") } @@ -514,7 +526,7 @@ func (r *nvIndexContext) SetAttr(a NVAttributes) { type sessionContext struct { *handleContext - attrs SessionAttributes + attrs SessionAttributes `tpm2:"ignore"` } func newSessionContext(handle Handle, data *sessionContextData) *sessionContext { @@ -529,7 +541,7 @@ func newSessionContext(handle Handle, data *sessionContextData) *sessionContext } } - return &sessionContext{ + out := &sessionContext{ handleContext: &handleContext{ HandleType: handleContextTypeSession, HandleHandle: handle, @@ -537,14 +549,12 @@ func newSessionContext(handle Handle, data *sessionContextData) *sessionContext Data: &handleContextU{Session: data}, }, } + out.disposeFns = []func(){out.handleContext.dispose} + return out } var _ SessionContext = (*sessionContext)(nil) -//func (r *sessionContext) Available() bool { -// return r.Data() != nil -//} - func (r *sessionContext) Params() SessionContextParams { d := r.Data() if d == nil {