Skip to content

Commit

Permalink
Fix ssh key format (#246)
Browse files Browse the repository at this point in the history
* ssh-keygen fix

* fix

* test on ssh-add compatible format

* fixing test, fixing cert path

* cleanup
  • Loading branch information
cviecco authored Oct 26, 2024
1 parent 35a5f3d commit 8c7799b
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 28 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ endif
BINARY=keymaster

# These are the values we want to pass for Version and BuildTime
VERSION?=1.15.4
VERSION?=1.15.5
DEFAULT_HOST?=
VERSION_FLAVOUR?=
EXTRA_LDFLAGS?=
Expand Down
6 changes: 3 additions & 3 deletions cmd/keymaster/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,19 +299,19 @@ func insertSSHCertIntoAgentORWriteToFilesystem(certText []byte,
return nil
}
logger.Debugf(1, "Non fatal, failed to insert into agent without expiration")
encodedSigner, err := x509.MarshalPKCS8PrivateKey(signer)
encodedSigner, err := ssh.MarshalPrivateKey(signer, "")
if err != nil {
return err
}
err = ioutil.WriteFile(
privateKeyPath,
pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: encodedSigner}),
pem.EncodeToMemory(encodedSigner),
0600)
if err != nil {
return err
}
// now we need to write the certificate
sshCertPath := privateKeyPath + ".pub"
sshCertPath := privateKeyPath + "-cert.pub"
return ioutil.WriteFile(sshCertPath, certText, 0644)
}

Expand Down
51 changes: 27 additions & 24 deletions cmd/keymaster/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import (
"crypto/rand"
"crypto/tls"
"crypto/x509"
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"os/exec"
"path/filepath"
"runtime"
"testing"
Expand All @@ -20,6 +20,7 @@ import (
"golang.org/x/crypto/ssh"

"github.com/Cloud-Foundations/golib/pkg/log/testlogger"
"github.com/Cloud-Foundations/keymaster/lib/certgen"
"github.com/Cloud-Foundations/keymaster/lib/client/config"
"github.com/Cloud-Foundations/keymaster/lib/client/twofa/u2f"
"github.com/Cloud-Foundations/keymaster/lib/client/util"
Expand Down Expand Up @@ -202,41 +203,29 @@ func TestMost(t *testing.T) {

}

func goCertToFileString(c ssh.Certificate, username string) (string, error) {
certBytes := c.Marshal()
encoded := base64.StdEncoding.EncodeToString(certBytes)
fileComment := "/tmp/" + username + "-" + c.SignatureKey.Type() + "-cert.pub"
return c.Type() + " " + encoded + " " + fileComment, nil
}

func TestInsertSSHCertIntoAgentORWriteToFilesystem(t *testing.T) {
//step 1: generate
publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
t.Fatal(err)
}

sshPublic, err := ssh.NewPublicKey(publicKey)
if err != nil {
t.Fatal(err)
}
cert := ssh.Certificate{
Key: sshPublic,
ValidPrincipals: []string{"username"},
ValidAfter: uint64(time.Now().Unix()) - 10,
ValidBefore: uint64(time.Now().Unix()) + 10,
}
sshPublicBytes := ssh.MarshalAuthorizedKey(sshPublic)

sshSigner, err := ssh.NewSignerFromKey(privateKey)
if err != nil {
t.Fatal(err)
}
err = cert.SignCert(rand.Reader, sshSigner)
if err != nil {
t.Fatal(err)
}
certString, err := goCertToFileString(cert, "username")
if err != nil {
t.Fatal(err)
}
seconds := 10
certDuration := time.Duration(seconds) * time.Second
extensions := make(map[string]string)

certString, _, err := certgen.GenSSHCertFileString("username", string(sshPublicBytes), sshSigner, "km.example.com", certDuration, extensions)

// This test needs a running agent... and remote windows
// builders do NOT have this... thus we need to abort this test
// until we have a way to NOT timeout on missing agent in
Expand Down Expand Up @@ -273,9 +262,23 @@ func TestInsertSSHCertIntoAgentORWriteToFilesystem(t *testing.T) {
if err != nil {
t.Fatal(err)
}
os.Remove(privateKeyPath)
// TODO: on linux/macos create agent + unix socket and pass that
defer os.Remove(privateKeyPath)

//t.Logf("certString='%s'", certString)

// TODO: on linux/macos create agent + unix socket and pass that
if oldSSHSock != "" && runtime.GOOS == "darwin" {
//reset the socket
err = os.Setenv("SSH_AUTH_SOCK", oldSSHSock)
if err != nil {
t.Fatal(err)
}
cmd := exec.Command("ssh-add", "-t", "30", privateKeyPath)
err := cmd.Run()
if err != nil {
t.Fatalf("Command finished with error: %v", err)
}
}
}

func TestMainSimple(t *testing.T) {
Expand Down

0 comments on commit 8c7799b

Please sign in to comment.