-
Notifications
You must be signed in to change notification settings - Fork 22
tpm2: Add WithLockoutAuthValue and WithLockoutAuthData options for EnsureProvisioned #533
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
Changes from all commits
36e4bf2
3c93e10
e8589f4
13bdb01
60a85c7
c40b1ee
910ac30
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -115,46 +115,78 @@ func (p *lockoutAuthParams) UnmarshalJSON(data []byte) error { | |
| return nil | ||
| } | ||
|
|
||
| func (t *Connection) resetDictionaryAttackLockImpl(params *lockoutAuthParams) error { | ||
| if len(params.NewAuthValue) > 0 || params.NewAuthPolicy != nil { | ||
| return errors.New("lockout hierarchy auth value change not supported yet") | ||
| // authorizeLockout authorizes the use of the lockout hierarchy using the supplied parameters for the | ||
| // specified command code. On success, a session is returned that can be used to authorize the specified | ||
| // command. The session is either a newly created policy session or the HMAC session returned from | ||
| // Connection.HmacSession. | ||
| // | ||
| // After using the authorization, the caller must execute the returned callback. | ||
| func (t *Connection) authorizeLockout(authParams *lockoutAuthParams, command tpm2.CommandCode) (session tpm2.SessionContext, lockoutAuthSet bool, done func(), err error) { | ||
| if len(authParams.NewAuthValue) > 0 || authParams.NewAuthPolicy != nil { | ||
| return nil, false, nil, errors.New("lockout hierarchy auth value change not supported yet") | ||
| } | ||
|
|
||
| var authValue []byte | ||
|
|
||
| val, err := t.GetCapabilityTPMProperty(tpm2.PropertyPermanent) | ||
| if err != nil { | ||
| return fmt.Errorf("cannot obtain value of TPM_PT_PERMANENT: %w", err) | ||
| return nil, false, nil, fmt.Errorf("cannot obtain value of TPM_PT_PERMANENT: %w", err) | ||
| } | ||
| lockoutAuthSet := tpm2.PermanentAttributes(val)&tpm2.AttrLockoutAuthSet > 0 | ||
| lockoutAuthSet = tpm2.PermanentAttributes(val)&tpm2.AttrLockoutAuthSet > 0 | ||
| if lockoutAuthSet { | ||
| authValue = params.AuthValue | ||
| authValue = authParams.AuthValue | ||
| } | ||
|
|
||
| var session tpm2.SessionContext | ||
| switch { | ||
| case params.AuthPolicy == nil: | ||
| case authParams.AuthPolicy == nil: | ||
| session = t.HmacSession() | ||
| default: | ||
| session, err = t.StartAuthSession(nil, nil, tpm2.SessionTypePolicy, nil, defaultSessionHashAlgorithm) | ||
| if err != nil { | ||
| return fmt.Errorf("cannot start policy session: %w", err) | ||
| return nil, false, nil, fmt.Errorf("cannot start policy session: %w", err) | ||
| } | ||
| defer t.FlushContext(session) | ||
| sessionInternal := session | ||
| defer func() { | ||
| if err == nil { | ||
| return | ||
| } | ||
| t.FlushContext(sessionInternal) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we flush only on error now, does this need a comment?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The session needs to live past the end of the function, so it returns a callback to flush the session in the non-error case. |
||
| }() | ||
|
|
||
| // Execute policy session, constraining the use to the TPM2_DictionaryAttackLockReset command so | ||
| // that the correct branch executes. | ||
| _, err := params.AuthPolicy.Execute( | ||
| _, err := authParams.AuthPolicy.Execute( | ||
| policyutil.NewPolicyExecuteSession(t.TPMContext, session), | ||
| policyutil.WithSessionUsageCommandConstraint(tpm2.CommandDictionaryAttackLockReset, []policyutil.NamedHandle{t.LockoutHandleContext()}), | ||
| policyutil.WithSessionUsageCommandCodeConstraint(command), | ||
| ) | ||
| if err != nil { | ||
| return ErrInvalidLockoutAuthPolicy | ||
| return nil, false, nil, ErrInvalidLockoutAuthPolicy | ||
| } | ||
| } | ||
|
|
||
| origAuthValue := t.LockoutHandleContext().AuthValue() | ||
| t.LockoutHandleContext().SetAuthValue(authValue) | ||
| defer t.LockoutHandleContext().SetAuthValue(nil) | ||
| defer func() { | ||
| if err == nil { | ||
| return | ||
| } | ||
| t.LockoutHandleContext().SetAuthValue(origAuthValue) | ||
| }() | ||
|
|
||
| return session, lockoutAuthSet, func() { | ||
| if authParams.AuthPolicy != nil { | ||
| t.FlushContext(session) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is the positive case flush now?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is. |
||
| } | ||
| t.LockoutHandleContext().SetAuthValue(origAuthValue) | ||
| }, nil | ||
| } | ||
|
|
||
| func (t *Connection) resetDictionaryAttackLockImpl(params *lockoutAuthParams) error { | ||
| session, lockoutAuthSet, done, err := t.authorizeLockout(params, tpm2.CommandDictionaryAttackLockReset) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| defer done() | ||
|
|
||
| switch err := t.DictionaryAttackLockReset(t.LockoutHandleContext(), session); { | ||
| case isAuthFailError(err, tpm2.CommandDictionaryAttackLockReset, 1): | ||
|
|
||
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.
this probably needs a doc comment now to explain what done is for