Skip to content

Commit

Permalink
move hardware key loading to execute loop
Browse files Browse the repository at this point in the history
  • Loading branch information
James-Pickett committed Dec 9, 2024
1 parent 1257fa0 commit 238b058
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 58 deletions.
50 changes: 22 additions & 28 deletions ee/secureenclaverunner/secureenclaverunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,54 +45,48 @@ func New(ctx context.Context, slogger *slog.Logger, store types.GetterSetterDele
ctx, span := traces.StartSpan(ctx)

Check failure on line 45 in ee/secureenclaverunner/secureenclaverunner.go

View workflow job for this annotation

GitHub Actions / lint (macos-latest)

ineffectual assignment to ctx (ineffassign)

Check failure on line 45 in ee/secureenclaverunner/secureenclaverunner.go

View workflow job for this annotation

GitHub Actions / lint (macos-latest)

ineffectual assignment to ctx (ineffassign)
defer span.End()

ser := &secureEnclaveRunner{
return &secureEnclaveRunner{
uidPubKeyMap: make(map[string]*ecdsa.PublicKey),
store: store,
secureEnclaveClient: secureEnclaveClient,
slogger: slogger.With("component", "secureenclaverunner"),
mux: &sync.Mutex{},
interrupt: make(chan struct{}),
}
}, nil
}

data, err := store.Get([]byte(publicEccDataKey))
// Public returns the public key of the current console user
// creating and peristing a new one if needed
func (ser *secureEnclaveRunner) Execute() error {
data, err := ser.store.Get([]byte(publicEccDataKey))
if err != nil {
traces.SetError(span, fmt.Errorf("getting public ecc data from store: %w", err))
return nil, fmt.Errorf("getting public ecc data from store: %w", err)
return fmt.Errorf("getting public ecc data from store: %w", err)
}

if data == nil {
return ser, nil
}

if err := json.Unmarshal(data, ser); err != nil {
traces.SetError(span, fmt.Errorf("unmarshaling secure enclave signer: %w", err))
ser.slogger.Log(ctx, slog.LevelError,
"unable to unmarshal secure enclave signer, data may be corrupt, wiping",
"err", err,
)

if err := store.Delete([]byte(publicEccDataKey)); err != nil {
traces.SetError(span, fmt.Errorf("deleting corrupt public ecc data: %w", err))
ser.slogger.Log(ctx, slog.LevelError,
if data != nil {
if err := json.Unmarshal(data, ser); err != nil {
ser.slogger.Log(context.TODO(), slog.LevelError,
"unable to unmarshal secure enclave signer, data may be corrupt, wiping",
"err", err,
)

if err := ser.store.Delete([]byte(publicEccDataKey)); err != nil {
ser.slogger.Log(context.TODO(), slog.LevelError,
"unable to unmarshal secure enclave signer, data may be corrupt, wiping",
"err", err,
)
}
}
}

return ser, nil
}

// Public returns the public key of the current console user
// creating and peristing a new one if needed
func (ser *secureEnclaveRunner) Execute() error {
currentRetryInterval, maxRetryInterval := 1*time.Second, 1*time.Minute
retryTicker := time.NewTicker(currentRetryInterval)
defer retryTicker.Stop()

for {
if _, err := ser.currentConsoleUserKey(context.TODO()); err != nil {
ser.slogger.Log(context.TODO(), slog.LevelError,
ctx := context.Background()
if _, err := ser.currentConsoleUserKey(ctx); err != nil {
ser.slogger.Log(ctx, slog.LevelError,
"getting current console user key, will retry",
"err", err,
)
Expand All @@ -109,7 +103,7 @@ func (ser *secureEnclaveRunner) Execute() error {
case <-retryTicker.C:
continue
case <-ser.interrupt:
ser.slogger.Log(context.TODO(), slog.LevelDebug,
ser.slogger.Log(ctx, slog.LevelDebug,
"interrupt received, exiting secure enclave signer execute loop",
)
return nil
Expand Down
8 changes: 8 additions & 0 deletions ee/secureenclaverunner/secureenclaverunner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ func Test_secureEnclaveRunner(t *testing.T) {
ser, err := New(context.TODO(), multislogger.NewNopLogger(), store, nil)
require.NoError(t, err)

go func() {
// sleep long enough to get through 2 cycles of exectue
time.Sleep(3 * time.Second)
ser.Interrupt(errors.New("test"))
}()

require.NoError(t, ser.Execute())

// should be able to fetch the key
require.NotNil(t, ser.Public())
})
Expand Down
52 changes: 23 additions & 29 deletions ee/tpmrunner/tpmrunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,31 @@ import (
"github.com/kolide/launcher/pkg/traces"
)

type tpmRunner struct {
signer crypto.Signer
signerCreator tpmSignerCreator
store types.GetterSetterDeleter
slogger *slog.Logger
interrupt chan struct{}
interrupted bool
}
type (
tpmRunner struct {
signer crypto.Signer
signerCreator tpmSignerCreator
store types.GetterSetterDeleter
slogger *slog.Logger
interrupt chan struct{}
interrupted bool
}

// tpmSignerCreator is an interface for creating and loading TPM signers
// useful for mocking in tests
type tpmSignerCreator interface {
CreateKey(opts ...tpm.TpmSignerOption) (private []byte, public []byte, err error)
New(private, public []byte) (crypto.Signer, error)
}
// tpmSignerCreator is an interface for creating and loading TPM signers
// useful for mocking in tests
tpmSignerCreator interface {
CreateKey(opts ...tpm.TpmSignerOption) (private []byte, public []byte, err error)
New(private, public []byte) (crypto.Signer, error)
}

// defaultTpmSignerCreator is the default implementation of tpmSignerCreator
// using the tpm package
defaultTpmSignerCreator struct{}

// defaultTpmSignerCreator is the default implementation of tpmSignerCreator
// using the tpm package
type defaultTpmSignerCreator struct{}
// tpmRunnerOption is a functional option for tpmRunner
// useful for setting dependencies in tests
tpmRunnerOption func(*tpmRunner)
)

// CreateKey creates a new TPM key
func (d defaultTpmSignerCreator) CreateKey(opts ...tpm.TpmSignerOption) (private []byte, public []byte, err error) {
Expand All @@ -44,19 +50,7 @@ func (d defaultTpmSignerCreator) New(private, public []byte) (crypto.Signer, err
return tpm.New(private, public)
}

// tpmRunnerOption is a functional option for tpmRunner
// useful for setting dependencies in tests
type tpmRunnerOption func(*tpmRunner)

func New(ctx context.Context, slogger *slog.Logger, store types.GetterSetterDeleter, opts ...tpmRunnerOption) (*tpmRunner, error) {
_, span := traces.StartSpan(ctx)
defer span.End()

_, _, err := fetchKeyData(store)
if err != nil {
return nil, err
}

tpmRunner := &tpmRunner{
store: store,
slogger: slogger.With("component", "tpmrunner"),
Expand Down
2 changes: 1 addition & 1 deletion ee/tpmrunner/tpmrunner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func withTpmSignerCreator(tpmSignerCreator tpmSignerCreator) tpmRunnerOption {
}
}

func Test_secureEnclaveSigner(t *testing.T) {
func Test_tpmRunner(t *testing.T) {
t.Parallel()

privKey, err := echelper.GenerateEcdsaKey()
Expand Down

0 comments on commit 238b058

Please sign in to comment.