Skip to content

Commit

Permalink
Add method to use ed25519 ssh key
Browse files Browse the repository at this point in the history
  • Loading branch information
slickwarren committed Aug 18, 2023
1 parent e3a8a4c commit c2783e2
Showing 1 changed file with 43 additions and 9 deletions.
52 changes: 43 additions & 9 deletions cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"encoding/pem"
"os"
"runtime"
"strings"
"sync"

"github.com/pkg/errors"
Expand All @@ -19,6 +20,7 @@ import (
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"golang.org/x/crypto/ed25519"
"golang.org/x/crypto/ssh"
"golang.org/x/sync/errgroup"
)
Expand All @@ -35,6 +37,7 @@ corral create k3s ghcr.io/rancher/k3s
corral create k3s-ha -v controlplane_count=3 ghcr.io/rancher/k3s
corral create k3s-custom /home/rancher/issue-1234
`
const ED25519_KEY_TYPE = "ed25519"

func NewCommandCreate() *cobra.Command {
cmd := &cobra.Command{
Expand Down Expand Up @@ -138,10 +141,21 @@ func create(cmd *cobra.Command, args []string) error {

if corr.Vars["corral_private_key"] == nil && corr.Vars["corral_public_key"] == nil {
logrus.Info("generating ssh keys")
privkey, _ := generatePrivateKey(2048)
pubkey, _ := generatePublicKey(&privkey.PublicKey)
corr.PrivateKey = string(encodePrivateKeyToPEM(privkey))
corr.PublicKey = string(pubkey)
if corr.Vars["corral_ssh_key_type"] == ED25519_KEY_TYPE {
_, privkey, _ := ed25519.GenerateKey(nil)
pubkey, err := ssh.NewPublicKey(privkey.Public())
if err != nil {
logrus.Fatal("failed to generate public ed25519 key: ", err)
}
corr.PrivateKey = string(encodePrivateKeyToPEM(privkey, "OPENSSH"))
corr.PublicKey = string(ssh.MarshalAuthorizedKey(pubkey))
} else {
corr.Vars["corral_ssh_key_type"] = "rsa"
privkey, _ := generateRSAPrivateKey(2048)
pubkey, _ := generateRSAPublicKey(&privkey.PublicKey)
corr.PrivateKey = string(encodePrivateKeyToPEM(privkey, "RSA"))
corr.PublicKey = string(pubkey)
}
corr.Vars["corral_public_key"] = corr.PublicKey
corr.Vars["corral_private_key"] = corr.PrivateKey
} else {
Expand Down Expand Up @@ -360,7 +374,7 @@ func executeShellCommandSync(command string, shells []*shell.Shell, vs vars.VarS
return nil
}

func generatePrivateKey(bits int) (*rsa.PrivateKey, error) {
func generateRSAPrivateKey(bits int) (*rsa.PrivateKey, error) {
privateKey, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return nil, err
Expand All @@ -374,7 +388,7 @@ func generatePrivateKey(bits int) (*rsa.PrivateKey, error) {
return privateKey, nil
}

func generatePublicKey(key *rsa.PublicKey) ([]byte, error) {
func generateRSAPublicKey(key *rsa.PublicKey) ([]byte, error) {
publicRsaKey, err := ssh.NewPublicKey(key)
if err != nil {
return nil, err
Expand All @@ -385,11 +399,31 @@ func generatePublicKey(key *rsa.PublicKey) ([]byte, error) {
return pubKeyBytes, nil
}

func encodePrivateKeyToPEM(key *rsa.PrivateKey) []byte {
privDER := x509.MarshalPKCS1PrivateKey(key)
func encodePrivateKeyToPEM(key any, blockType string) []byte {
blockTypeDefault := "PRIVATE KEY"

if len(blockType) > 0 {
blockTypeDefault = " " + blockTypeDefault
}
blockType = blockType + blockTypeDefault

var privDER []byte
var err error
if strings.Contains(blockType, "OPENSSH") {
// Necessary to cast type in order to correctly marshal the key for OpenSSH
privDER, _ = x509.MarshalPKCS8PrivateKey(key.(ed25519.PrivateKey))
} else if strings.Contains(blockType, "RSA") {
privDER = x509.MarshalPKCS1PrivateKey(key.(*rsa.PrivateKey))
} else {
privDER, err = x509.MarshalPKCS8PrivateKey(key)
}

if err != nil {
logrus.Fatal("failed to marshal PKCS8 private key: ", err)
}

privBlock := pem.Block{
Type: "RSA PRIVATE KEY",
Type: blockType,
Headers: nil,
Bytes: privDER,
}
Expand Down

0 comments on commit c2783e2

Please sign in to comment.