Skip to content

Commit

Permalink
add support for persistent srk
Browse files Browse the repository at this point in the history
* Persisting the SRK allows the creation and use of individual keys
  without specifying the owner password
  • Loading branch information
novag committed May 24, 2024
1 parent 1c7bced commit 5b2786a
Show file tree
Hide file tree
Showing 11 changed files with 229 additions and 88 deletions.
7 changes: 5 additions & 2 deletions agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/rand"
"errors"
"fmt"
"github.com/google/go-tpm/tpm2"
"io"
"io/fs"
"net"
Expand All @@ -30,6 +31,7 @@ type Agent struct {
mu sync.Mutex
tpm func() transport.TPMCloser
op func() ([]byte, error)
srk tpm2.TPMHandle
pin func(*key.Key) ([]byte, error)
listener *net.UnixListener
quit chan interface{}
Expand Down Expand Up @@ -84,7 +86,7 @@ func (a *Agent) signers() ([]ssh.Signer, error) {
}

for _, k := range a.keys {
s, err := ssh.NewSignerFromSigner(signer.NewTPMSigner(k, a.op, a.tpm, a.pin))
s, err := ssh.NewSignerFromSigner(signer.NewTPMSigner(k, a.op, a.srk, a.tpm, a.pin))
if err != nil {
return nil, fmt.Errorf("failed to prepare signer: %w", err)
}
Expand Down Expand Up @@ -344,11 +346,12 @@ func LoadKeys(keyDir string) (map[string]*key.Key, error) {
return keys, err
}

func NewAgent(listener *net.UnixListener, agents []agent.ExtendedAgent, tpmFetch func() transport.TPMCloser, ownerPassword func() ([]byte, error), pin func(*key.Key) ([]byte, error)) *Agent {
func NewAgent(listener *net.UnixListener, agents []agent.ExtendedAgent, srkHandle tpm2.TPMHandle, tpmFetch func() transport.TPMCloser, ownerPassword func() ([]byte, error), pin func(*key.Key) ([]byte, error)) *Agent {
a := &Agent{
agents: agents,
tpm: tpmFetch,
op: ownerPassword,
srk: srkHandle,
listener: listener,
pin: pin,
quit: make(chan interface{}),
Expand Down
3 changes: 2 additions & 1 deletion agent/agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func TestAddKey(t *testing.T) {

ag := NewAgent(unixList,
[]agent.ExtendedAgent{},
0x0,
// TPM Callback
func() transport.TPMCloser { return tpm },
// Owner password
Expand All @@ -47,7 +48,7 @@ func TestAddKey(t *testing.T) {

client := agent.NewClient(conn)

k, err := key.CreateKey(tpm, tpm2.TPMAlgECC, 256, []byte(""), []byte(""), "")
k, err := key.CreateKey(tpm, tpm2.TPMAlgECC, 256, []byte(""), 0x0, []byte(""), "")
if err != nil {
t.Fatal(err)
}
Expand Down
20 changes: 15 additions & 5 deletions cmd/ssh-tpm-agent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ Options:
-o, --owner-password Ask for the owner password.
-s, --srk-handle Persist the storage root key at the specified handle.
-d Enable debug logging.
--install-user-units Installs systemd system units and sshd configs for using
Expand Down Expand Up @@ -100,10 +102,10 @@ func main() {
}

var (
socketPath, keyDir string
swtpmFlag, printSocketFlag bool
installUserUnits, system, noLoad bool
askOwnerPassword, debugMode bool
socketPath, keyDir, srkHandleInput string
swtpmFlag, printSocketFlag bool
installUserUnits, system, noLoad bool
askOwnerPassword, debugMode bool
)

envSocketPath := func() string {
Expand All @@ -130,6 +132,8 @@ func main() {
flag.BoolVar(&noLoad, "no-load", false, "don't load TPM sealed keys")
flag.BoolVar(&askOwnerPassword, "o", false, "ask for the owner password")
flag.BoolVar(&askOwnerPassword, "owner-password", false, "ask for the owner password")
flag.StringVar(&srkHandleInput, "s", "", "persist the SRK to the specified handle")
flag.StringVar(&srkHandleInput, "srk-handle", "", "persist the SRK to the specified handle")
flag.BoolVar(&debugMode, "d", false, "debug mode")
flag.Parse()

Expand All @@ -145,6 +149,12 @@ func main() {

slog.SetDefault(logger)

// Parse srk handle
srkHandle, err := utils.ParseHexHandle(srkHandleInput)
if err != nil {
log.Fatal(err)
}

if installUserUnits {
if err := utils.InstallUserUnits(system); err != nil {
log.Fatal(err)
Expand Down Expand Up @@ -193,7 +203,7 @@ func main() {
os.Exit(1)
}

agent := agent.NewAgent(listener, agents,
agent := agent.NewAgent(listener, agents, srkHandle,

// TPM Callback
func() (tpm transport.TPMCloser) {
Expand Down
1 change: 1 addition & 0 deletions cmd/ssh-tpm-agent/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ func runSSHAuth(t *testing.T, keytype tpm2.TPMAlgID, bits int, pin []byte, keyfn

ag := agent.NewAgent(unixList,
[]sshagent.ExtendedAgent{},
0x0,
// TPM Callback
func() transport.TPMCloser { return tpm },
// Owner password
Expand Down
20 changes: 15 additions & 5 deletions cmd/ssh-tpm-keygen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const usage = `Usage:
Options:
-o, --owner-password Ask for the owner password.
-s, --srk-handle Persist the storage root key at the specified handle.
-C Provide a comment with the key.
-f Output keyfile.
-N PIN for the key.
Expand Down Expand Up @@ -113,7 +114,8 @@ func main() {

var (
askOwnerPassword bool
comment, outputFile, keyPin string
srkHandleInput, comment string
outputFile, keyPin string
keyType, importKey string
bits int
swtpmFlag, hostKeys, changePin bool
Expand All @@ -138,6 +140,8 @@ func main() {

flag.BoolVar(&askOwnerPassword, "o", false, "ask for the owner password")
flag.BoolVar(&askOwnerPassword, "owner-password", false, "ask for the owner password")
flag.StringVar(&srkHandleInput, "s", "", "persist the SRK to the specified handle")
flag.StringVar(&srkHandleInput, "srk-handle", "", "persist the SRK to the specified handle")
flag.StringVar(&comment, "C", defaultComment, "provide a comment, default to user@host")
flag.StringVar(&outputFile, "f", "", "output keyfile")
flag.StringVar(&keyPin, "N", "", "new pin for the key")
Expand Down Expand Up @@ -187,6 +191,12 @@ func main() {
ownerPassword = []byte("")
}

// Parse srk handle
srkHandle, err := utils.ParseHexHandle(srkHandleInput)
if err != nil {
log.Fatal(err)
}

// Generate host keys
if hostKeys {
// Mimics the `ssh-keygen -A -f ./something` behaviour
Expand All @@ -213,7 +223,7 @@ func main() {

slog.Info("Generating new host key", slog.String("algorithm", strings.ToUpper(n)))

k, err := key.CreateKey(tpm, t.alg, t.bits, ownerPassword, []byte(""), defaultComment)
k, err := key.CreateKey(tpm, t.alg, t.bits, ownerPassword, srkHandle, []byte(""), defaultComment)
if err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -298,7 +308,7 @@ func main() {
}
fmt.Println()

newkey, err := key.ChangeAuth(tpm, ownerPassword, k, oldPin, newPin)
newkey, err := key.ChangeAuth(tpm, ownerPassword, srkHandle, k, oldPin, newPin)
if err != nil {
log.Fatal("Failed changing pin on the key.")
}
Expand Down Expand Up @@ -432,12 +442,12 @@ func main() {

if importKey != "" {
// TODO: Read public key for comment
k, err = key.ImportKey(tpm, ownerPassword, toImportKey, pin, comment)
k, err = key.ImportKey(tpm, ownerPassword, srkHandle, toImportKey, pin, comment)
if err != nil {
log.Fatal(err)
}
} else {
k, err = key.CreateKey(tpm, tpmkeyType, bits, ownerPassword, pin, comment)
k, err = key.CreateKey(tpm, tpmkeyType, bits, ownerPassword, srkHandle, pin, comment)
if err != nil {
log.Fatal(err)
}
Expand Down
4 changes: 2 additions & 2 deletions internal/keytest/keytest.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func MkECDSA(t *testing.T, a elliptic.Curve) ecdsa.PrivateKey {
// Test helper for CreateKey
func MkKey(t *testing.T, tpm transport.TPMCloser, keytype tpm2.TPMAlgID, bits int, pin []byte, comment string) (*key.Key, error) {
t.Helper()
return key.CreateKey(tpm, keytype, bits, []byte(""), pin, comment)
return key.CreateKey(tpm, keytype, bits, []byte(""), 0x0, pin, comment)
}

// Helper to make an importable key
Expand All @@ -56,7 +56,7 @@ func MkImportableKey(t *testing.T, tpm transport.TPMCloser, keytype tpm2.TPMAlgI
case tpm2.TPMAlgRSA:
pk = MkRSA(t, bits)
}
return key.ImportKey(tpm, []byte(""), pk, pin, comment)
return key.ImportKey(tpm, []byte(""), 0x0, pk, pin, comment)
}

// Give us some random bytes
Expand Down
Loading

0 comments on commit 5b2786a

Please sign in to comment.