Skip to content
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

hardware key runners #1977

Merged
merged 28 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3f86421
rough draft
James-Pickett Dec 4, 2024
4c99f30
fix race, reset runner ticker
James-Pickett Dec 5, 2024
5bd7d17
lint
James-Pickett Dec 5, 2024
207b4c9
add tracing to tpm runner
James-Pickett Dec 5, 2024
d35e9af
comments
James-Pickett Dec 5, 2024
111f095
fix client path
James-Pickett Dec 5, 2024
165852e
more comments
James-Pickett Dec 5, 2024
805019c
invert secure enclave runner return
James-Pickett Dec 6, 2024
124c2a4
remove unneeded no lint directives
James-Pickett Dec 6, 2024
1257fa0
fix comment
James-Pickett Dec 6, 2024
238b058
move hardware key loading to execute loop
James-Pickett Dec 9, 2024
ffc708b
lint
James-Pickett Dec 9, 2024
5c2a107
add multiplicative ticker, use in runners
James-Pickett Dec 9, 2024
cc011e5
lint
James-Pickett Dec 9, 2024
257ce99
increase ticker test buffer
James-Pickett Dec 9, 2024
f2192ad
use post to crate secure enclave key
James-Pickett Dec 9, 2024
53f1bf1
add multiple interrupt tests
James-Pickett Dec 9, 2024
ed176a3
update tpm runner to also support on demand key creation
James-Pickett Dec 11, 2024
7885001
start span before mutex lock
James-Pickett Dec 11, 2024
905bf82
handle case in execute where no console users, wait longer
James-Pickett Dec 12, 2024
14c0671
spelling
James-Pickett Dec 12, 2024
84a3a2c
give up on custom ticker, reset ticker in execute to back off
James-Pickett Dec 13, 2024
6c819bc
comments
James-Pickett Dec 13, 2024
9457974
make secure enclave loop more readable
James-Pickett Dec 13, 2024
c8cceea
log errors
James-Pickett Dec 13, 2024
d1f8158
feedback
James-Pickett Dec 18, 2024
2ffdc97
Merge branch 'main' into james/hardware-key-runners
James-Pickett Dec 18, 2024
121fc22
Merge branch 'main' into james/hardware-key-runners
James-Pickett Dec 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion cmd/launcher/launcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ func runLauncher(ctx context.Context, cancel func(), multiSlogger, systemMultiSl
if err := osquery.SetupLauncherKeys(k.ConfigStore()); err != nil {
return fmt.Errorf("setting up initial launcher keys: %w", err)
}
if err := agent.SetupKeys(ctx, k.Slogger(), k.ConfigStore(), false); err != nil {
if err := agent.SetupKeys(ctx, k.Slogger(), k.ConfigStore()); err != nil {
return fmt.Errorf("setting up agent keys: %w", err)
}

Expand Down Expand Up @@ -434,6 +434,12 @@ func runLauncher(ctx context.Context, cancel func(), multiSlogger, systemMultiSl
return fmt.Errorf("failed to create desktop runner: %w", err)
}

execute, interrupt, err := agent.SetHardwareKeysRunner(ctx, k.Slogger(), k.ConfigStore(), runner)
if err != nil {
return fmt.Errorf("setting up hardware keys: %w", err)
}
runGroup.Add("hardwareKeys", execute, interrupt)

runGroup.Add("desktopRunner", runner.Execute, runner.Interrupt)
controlService.RegisterConsumer(desktopMenuSubsystemName, runner)

Expand Down
2 changes: 0 additions & 2 deletions cmd/launcher/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,6 @@ func runSubcommands(systemMultiSlogger *multislogger.MultiSlogger) error {
run = runDownloadOsquery
case "uninstall":
run = runUninstall
case "secure-enclave":
run = runSecureEnclave
case "watchdog": // note: this is currently only implemented for windows
run = watchdog.RunWatchdogTask
default:
Expand Down
49 changes: 0 additions & 49 deletions cmd/launcher/secure_enclave_darwin.go

This file was deleted.

14 changes: 0 additions & 14 deletions cmd/launcher/secure_enclave_other.go

This file was deleted.

154 changes: 0 additions & 154 deletions cmd/launcher/secure_enclave_test.go

This file was deleted.

82 changes: 6 additions & 76 deletions ee/agent/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@ package agent
import (
"context"
"crypto"
"crypto/ecdsa"
"fmt"
"log/slog"
"time"

"github.com/kolide/launcher/ee/agent/keys"
"github.com/kolide/launcher/ee/agent/types"
"github.com/kolide/launcher/pkg/backoff"
"github.com/kolide/launcher/pkg/traces"
)

type keyInt interface {
Expand All @@ -21,6 +19,7 @@ type keyInt interface {
var hardwareKeys keyInt = keys.Noop
var localDbKeys keyInt = keys.Noop

// HardwareKeys returns the hardware keys for the agent, it's critical to not cache this value as it may change during runtime.
func HardwareKeys() keyInt {
return hardwareKeys
}
Expand All @@ -29,10 +28,11 @@ func LocalDbKeys() keyInt {
return localDbKeys
}

func SetupKeys(ctx context.Context, slogger *slog.Logger, store types.GetterSetterDeleter, skipHardwareKeys bool) error {
ctx, span := traces.StartSpan(ctx)
defer span.End()
type secureEnclaveClient interface {
CreateSecureEnclaveKey(uid string) (*ecdsa.PublicKey, error)
}

func SetupKeys(_ context.Context, slogger *slog.Logger, store types.GetterSetterDeleter) error {
slogger = slogger.With("component", "agentkeys")

var err error
Expand All @@ -43,75 +43,5 @@ func SetupKeys(ctx context.Context, slogger *slog.Logger, store types.GetterSett
return fmt.Errorf("setting up local db keys: %w", err)
}

if skipHardwareKeys {
return nil
}

err = backoff.WaitFor(func() error {
hwKeys, err := setupHardwareKeys(ctx, slogger, store)
if err != nil {
return err
}
hardwareKeys = hwKeys
return nil
}, 1*time.Second, 250*time.Millisecond)

if err != nil {
// Use of hardware keys is not fully implemented as of 2023-02-01, so log an error and move on
slogger.Log(context.TODO(), slog.LevelInfo,
"failed setting up hardware keys",
"err", err,
)
}

return nil
}

// This duplicates some of pkg/osquery/extension.go but that feels like the wrong place.
// Really, we should have a simpler interface over a storage layer.
const (
privateEccData = "privateEccData" // nolint:unused
publicEccData = "publicEccData" // nolint:unused
)

// nolint:unused
func fetchKeyData(store types.Getter) ([]byte, []byte, error) {
pri, err := store.Get([]byte(privateEccData))
if err != nil {
return nil, nil, err
}

pub, err := store.Get([]byte(publicEccData))
if err != nil {
return nil, nil, err
}

return pri, pub, nil
}

// nolint:unused
func storeKeyData(store types.Setter, pri, pub []byte) error {
if pri != nil {
if err := store.Set([]byte(privateEccData), pri); err != nil {
return err
}
}

if pub != nil {
if err := store.Set([]byte(publicEccData), pub); err != nil {
return err
}
}

return nil
}

// clearKeyData is used to clear the keys as part of error handling around new keys. It is not intended to be called
// regularly, and since the path that calls it is around DB errors, it has no error handling.
// nolint:unused
func clearKeyData(slogger *slog.Logger, deleter types.Deleter) {
slogger.Log(context.TODO(), slog.LevelInfo,
"clearing keys",
)
_ = deleter.Delete([]byte(privateEccData), []byte(publicEccData))
}
13 changes: 8 additions & 5 deletions ee/agent/keys_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,22 @@ import (
"log/slog"

"github.com/kolide/launcher/ee/agent/types"
"github.com/kolide/launcher/ee/secureenclavesigner"
"github.com/kolide/launcher/ee/secureenclaverunner"
"github.com/kolide/launcher/pkg/traces"
)

func setupHardwareKeys(ctx context.Context, slogger *slog.Logger, store types.GetterSetterDeleter) (keyInt, error) {
// SetHardwareKeysRunner creates a secure enclave runner and sets it as the agent hardware key as it also implements the keyInt/cyrpto.Signer interface.
James-Pickett marked this conversation as resolved.
Show resolved Hide resolved
// The returned execute and interrupt functions can be used to start and stop the secure enclave runner, generally via a run group.
func SetHardwareKeysRunner(ctx context.Context, slogger *slog.Logger, store types.GetterSetterDeleter, secureEnclaveClient secureEnclaveClient) (execute func() error, interrupt func(error), err error) {
ctx, span := traces.StartSpan(ctx)
defer span.End()

ses, err := secureenclavesigner.New(ctx, slogger, store)
ser, err := secureenclaverunner.New(ctx, slogger, store, secureEnclaveClient)
if err != nil {
traces.SetError(span, fmt.Errorf("creating secureenclave signer: %w", err))
return nil, fmt.Errorf("creating secureenclave signer: %w", err)
return nil, nil, fmt.Errorf("creating secureenclave signer: %w", err)
}

return ses, nil
hardwareKeys = ser
return ser.Execute, ser.Interrupt, nil
}
Loading
Loading