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

james/secure enclave cmd signer #1514

Closed

Conversation

James-Pickett
Copy link
Contributor

@James-Pickett James-Pickett commented Dec 15, 2023

This PR sets up the ground for execing secure enclave in user ctx.

The broad strokes are:

ee/secureenclavesigner is a struct that implements the cyrpto.Signer interface. Its implementation of the the Public() and Sign() functions will exec out to new launcher secure-enclave subcommand when needed. Since the secureEnclaveSigner implements crypto.Signer it can be passed to the krypto/challenge package to sign responses.

follow on PRs:

  • add tracing and logging
  • update local server to use secureenclavesigner

related krypto PR: kolide/krypto#35

@James-Pickett James-Pickett changed the title james/secure enclave cmd signer [DO NOT MERGE] james/secure enclave cmd signer Dec 15, 2023
"github.com/vmihailenco/msgpack/v5"
)

type SignRequest struct {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kinda weird that some are []bytes of b64 strings ... wonder if they should all be b64 string or all just straight []byte

pathToLauncherBinary string
}

func New(uid string, challenge []byte, opts ...opt) (*secureEnclaveSigner, error) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we go ahead and create / verify the key exists in secure enclave in the new func? Fail faster at the expense of a possible extra exec?

cmd/launcher/secure_enclave_dawin.go Outdated Show resolved Hide resolved
cmd/launcher/secure_enclave_dawin.go Outdated Show resolved Hide resolved
cmd/launcher/secure_enclave_dawin.go Outdated Show resolved Hide resolved
cmd/launcher/secure_enclave_dawin.go Outdated Show resolved Hide resolved
cmd/launcher/secure_enclave_dawin.go Outdated Show resolved Hide resolved
cmd/launcher/secure_enclave_test.go Outdated Show resolved Hide resolved
ee/secureenclavesigner/secureenclavesigner_test.go Outdated Show resolved Hide resolved
ee/secureenclavesigner/secureenclavesigner.go Outdated Show resolved Hide resolved
ee/secureenclavesigner/secureenclavesigner.go Outdated Show resolved Hide resolved
pkg/tools/tools.go Outdated Show resolved Hide resolved
@James-Pickett James-Pickett changed the title [DO NOT MERGE] james/secure enclave cmd signer james/secure enclave cmd signer Dec 27, 2023
@James-Pickett James-Pickett marked this pull request as ready for review December 27, 2023 18:22
cmd/launcher/secure_enclave_dawin.go Outdated Show resolved Hide resolved
cmd/launcher/secure_enclave_dawin.go Outdated Show resolved Hide resolved
cmd/launcher/secure_enclave_dawin.go Outdated Show resolved Hide resolved
cmd/launcher/secure_enclave_dawin.go Outdated Show resolved Hide resolved
cmd/launcher/secure_enclave_dawin.go Outdated Show resolved Hide resolved
cmd/launcher/secure_enclave_dawin.go Outdated Show resolved Hide resolved
ee/secureenclavesigner/secureenclavesigner.go Outdated Show resolved Hide resolved
ee/secureenclavesigner/secureenclavesigner_test.go Outdated Show resolved Hide resolved
ee/secureenclavesigner/secureenclavesigner_test.go Outdated Show resolved Hide resolved
cmd/launcher/secure_enclave_dawin.go Outdated Show resolved Hide resolved
cmd/launcher/secure_enclave_darwin.go Outdated Show resolved Hide resolved
cmd/launcher/secure_enclave_darwin.go Outdated Show resolved Hide resolved
ee/secureenclavesigner/test_keys.go Outdated Show resolved Hide resolved
}
}

func createSecureEnclaveKey(requestB64 string) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I know enough to know, but do we need to do any kind of tracking around which k2 key requested this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how or where we could track this? We could put it in logs and the way we do with desktop

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talking aloud... If we create a key for a developer environment, and then get a signing request for the prod environment, what do we do? (or vice versa)

I'm not sure there's a security issue here, but I'm not sure how launcher picks the correct key to sign the response with.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This ends up tying up to the deletion comments above)

cmd/launcher/secure_enclave_darwin.go Show resolved Hide resolved
cmd/launcher/secure_enclave_dawin.go Outdated Show resolved Hide resolved
cmd/launcher/secure_enclave_darwin.go Show resolved Hide resolved
cmd/launcher/secure_enclave_darwin.go Outdated Show resolved Hide resolved
ee/secureenclavesigner/secureenclavesigner.go Outdated Show resolved Hide resolved
RebeccaMahany
RebeccaMahany previously approved these changes Jan 19, 2024
var serverPubKeys = make(map[string]*ecdsa.PublicKey)

// runSecureEnclave performs either a create-key or sign operation using the secure enclave.
// It's available as a separate command because launcher runs a root by default and since it's
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(nitpick -- typo)

Suggested change
// It's available as a separate command because launcher runs a root by default and since it's
// It's available as a separate command because launcher runs as root by default and since it's

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(this now says aa instead of as)

@directionless
Copy link
Contributor

(Please don't merge this yet)

return fmt.Errorf("creating secure enclave signer: %w", err)
}

digest, err := echelper.HashForSignature(challenge.Msg)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this what we want to sign? Or do we want to pull some specific field out of the Msg?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the existing code paths?

ee/localserver/request-id.go Outdated Show resolved Hide resolved
go.mod Outdated Show resolved Hide resolved
Copy link
Contributor

@RebeccaMahany RebeccaMahany left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New changes LGTM too

ee/secureenclavesigner/secureenclavesigner.go Outdated Show resolved Hide resolved
cmd/launcher/secure_enclave_darwin.go Outdated Show resolved Hide resolved
}

func loadServerKeys() error {
if secureenclavesigner.Undertest {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this should never trigger in real use, I kinda want a giant log warning for this condition. (But I see slogger isn't here yet)

}
}

func createSecureEnclaveKey(requestB64 string) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talking aloud... If we create a key for a developer environment, and then get a signing request for the prod environment, what do we do? (or vice versa)

I'm not sure there's a security issue here, but I'm not sure how launcher picks the correct key to sign the response with.

return errors.New("missing request")
}

switch args[0] {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about deletion/uninstall.

As it stands today, the uninstall message is not signed. So how do we uninstall these keys? Do we need to?

If we need to delete them, we probably need a signed deletion message.

If we don't need to, we could do somewhere where launcher records a nonce in the launcherdb, and then we pass the nonce along to the sign command. (so that we can find the correct key). (And by nonce, I probably mean the public key, we could stash it in the launcher db. Though that will be weird cross users. Probably still correct)

}
}

func createSecureEnclaveKey(requestB64 string) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This ends up tying up to the deletion comments above)

return fmt.Errorf("creating secure enclave signer: %w", err)
}

digest, err := echelper.HashForSignature(challenge.Msg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the existing code paths?

cmd/launcher/secure_enclave_darwin.go Show resolved Hide resolved
Comment on lines 57 to 60
// uid is the uid of the user to run the secure enclave commands as
uid string
// username is the username of the user to run the secure enclave commands as
username string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need both?

return errors.New("missing request")
}

switch args[0] {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it's a usability win, but I wonder if we can discern what kind of request it is from the signed blob.

}

if runtime.GOOS == "darwin" {
requestDataWithUserSig, err := e.addUserSignature(r.Context(), response, *challengeBox)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just go ahead and add a UserSig or MachineSig for all platforms? We could just do the same behavior with TPM.

@James-Pickett
Copy link
Contributor Author

closing in favor of completing #1644 first

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants