Skip to content

Commit

Permalink
ssh-agent-tpm: Implement rsa support
Browse files Browse the repository at this point in the history
Signed-off-by: Morten Linderud <morten@linderud.pw>
  • Loading branch information
Foxboron committed Aug 5, 2023
1 parent 81f5cef commit a8f4676
Show file tree
Hide file tree
Showing 6 changed files with 279 additions and 78 deletions.
3 changes: 2 additions & 1 deletion agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,8 @@ func LoadKeys() (map[string]*key.Key, error) {
}
k, err := key.DecodeKey(f)
if err != nil {
return fmt.Errorf("%s not a TPM sealed key: %v", path, err)
log.Printf("%s not a TPM sealed key: %v\n", path, err)
return nil
}
sshpubkey, err := k.SSHPublicKey()
if err != nil {
Expand Down
24 changes: 18 additions & 6 deletions cmd/ssh-tpm-agent/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"github.com/foxboron/ssh-tpm-agent/agent"
"github.com/foxboron/ssh-tpm-agent/key"
"github.com/google/go-tpm/tpm2"
"github.com/google/go-tpm/tpm2/transport"
"github.com/google/go-tpm/tpm2/transport/simulator"
"golang.org/x/crypto/ssh"
Expand All @@ -32,7 +33,8 @@ func newSSHKey() ssh.Signer {
return signer
}

func setupServer(clientKey ssh.PublicKey) (hostkey ssh.PublicKey, msgSent chan bool) {
func setupServer(clientKey ssh.PublicKey) (hostkey ssh.PublicKey, msgSent chan bool, listener net.Listener) {
var err error
hostSigner := newSSHKey()
msgSent = make(chan bool)

Expand All @@ -57,7 +59,7 @@ func setupServer(clientKey ssh.PublicKey) (hostkey ssh.PublicKey, msgSent chan b
config.AddHostKey(hostSigner)

go func() {
listener, err := net.Listen("tcp", "127.0.0.1:2022")
listener, err = net.Listen("tcp", "127.0.0.1:2022")
if err != nil {
log.Fatal("failed to listen for connection: ", err)
}
Expand Down Expand Up @@ -105,16 +107,16 @@ func setupServer(clientKey ssh.PublicKey) (hostkey ssh.PublicKey, msgSent chan b
// Waiting until the server has started
<-srvStart

return hostSigner.PublicKey(), msgSent
return hostSigner.PublicKey(), msgSent, listener
}

func TestSSHAuth(t *testing.T) {
func runSSHAuth(t *testing.T, keytype tpm2.TPMAlgID) {
tpm, err := simulator.OpenSimulator()
if err != nil {
t.Fatal(err)
}

k, err := key.CreateKey(tpm, []byte(""))
k, err := key.CreateKey(tpm, keytype, []byte(""))
if err != nil {
t.Fatalf("failed creating key: %v", err)
}
Expand All @@ -123,7 +125,8 @@ func TestSSHAuth(t *testing.T) {
t.Fatalf("failed getting ssh public key")
}

hostkey, msgSent := setupServer(clientKey)
hostkey, msgSent, listener := setupServer(clientKey)
defer listener.Close()

socket := path.Join(t.TempDir(), "socket")

Expand Down Expand Up @@ -174,3 +177,12 @@ func TestSSHAuth(t *testing.T) {
t.Fatalf("failed to connect")
}
}

func TestSSHAuth(t *testing.T) {
t.Run("ecdsa - agent", func(t *testing.T) {
runSSHAuth(t, tpm2.TPMAlgECDSA)
})
t.Run("rsa - agent", func(t *testing.T) {
runSSHAuth(t, tpm2.TPMAlgRSA)
})
}
42 changes: 35 additions & 7 deletions cmd/ssh-tpm-keygen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/foxboron/ssh-tpm-agent/agent"
"github.com/foxboron/ssh-tpm-agent/key"
"github.com/foxboron/ssh-tpm-agent/utils"
"github.com/google/go-tpm/tpm2"
"golang.org/x/crypto/ssh"
"golang.org/x/term"
)
Expand All @@ -26,9 +27,10 @@ const usage = `Usage:
ssh-tpm-keygen
Options:
-C Comment WIP
-f Output keyfile WIP
-N PIN for the key WIP
-C Comment WIP
-f Output keyfile WIP
-N PIN for the key WIP
-t ecdsa | rsa Specify the type of key to create. Defaults to ecdsa
Generate new TPM sealed keys for ssh-tpm-agent.
Expand Down Expand Up @@ -97,19 +99,34 @@ func main() {

var (
comment, outputFile, keyPin string
keyType string
swtpmFlag bool
)

flag.StringVar(&comment, "C", "", "provide a comment with the key")
flag.StringVar(&outputFile, "f", "", "output keyfile")
flag.StringVar(&keyPin, "N", "", "new pin for the key")
flag.StringVar(&keyType, "t", "ecdsa", "key to create")
flag.BoolVar(&swtpmFlag, "swtpm", false, "use swtpm instead of actual tpm")

flag.Parse()

fmt.Println("Generating a sealed public/private ecdsa key pair.")
var tpmkeyType tpm2.TPMAlgID
var filename string

switch keyType {
case "ecdsa":
tpmkeyType = tpm2.TPMAlgECDSA
filename = "id_ecdsa"
case "rsa":
tpmkeyType = tpm2.TPMAlgRSA
filename = "id_rsa"
}

fmt.Printf("Generating a sealed public/private %s key pair.\n", keyType)

filename = path.Join(agent.GetSSHDir(), filename)

filename := path.Join(agent.GetSSHDir(), "id_ecdsa")
filenameInput, err := getStdin("Enter file in which to save the key (%s): ", filename)
if err != nil {
log.Fatal(err)
Expand All @@ -119,6 +136,7 @@ func main() {
}

privatekeyFilename := filename + ".tpm"
pubkeyFilename := filename + ".pub"

if fileExists(privatekeyFilename) {
fmt.Printf("%s already exists.\n", privatekeyFilename)
Expand All @@ -130,6 +148,16 @@ func main() {
return
}
}
if fileExists(pubkeyFilename) {
fmt.Printf("%s already exists.\n", pubkeyFilename)
s, err := getStdin("Overwrite (y/n)?")
if err != nil {
log.Fatal(err)
}
if s != "y" {
return
}
}

var pin []byte
pinInput := getPin()
Expand All @@ -142,7 +170,7 @@ func main() {
log.Fatal(err)
}
defer tpm.Close()
k, err := key.CreateKey(tpm, pin)
k, err := key.CreateKey(tpm, tpmkeyType, pin)
if err != nil {
log.Fatal(err)
}
Expand All @@ -151,7 +179,7 @@ func main() {
if err != nil {
log.Fatal(err)
}
pubkeyFilename := filename + ".pub"

if err := os.WriteFile(pubkeyFilename, ssh.MarshalAuthorizedKey(sshKey), 0644); err != nil {
log.Fatal(err)
}
Expand Down
Loading

0 comments on commit a8f4676

Please sign in to comment.