mirror of https://github.com/kubernetes/kops.git
Shell out to ssh-keygen for creating ed25519 keys
Go's crypto modules can't generate ed25519 keys in the openssh format, so we rely on ssh-keygen instead
This commit is contained in:
parent
3242dc3cb4
commit
f9c0487fbf
|
@ -7,7 +7,6 @@ require (
|
|||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||
github.com/octago/sflags v0.2.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3
|
||||
k8s.io/api v0.23.5
|
||||
k8s.io/apimachinery v0.23.5
|
||||
k8s.io/client-go v9.0.0+incompatible
|
||||
|
@ -123,6 +122,7 @@ require (
|
|||
github.com/xanzy/ssh-agent v0.3.1 // indirect
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
|
|
|
@ -17,72 +17,29 @@ limitations under the License.
|
|||
package util
|
||||
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
"sigs.k8s.io/kubetest2/pkg/exec"
|
||||
)
|
||||
|
||||
// CreateSSHKeyPair creates a key pair in a temp directory
|
||||
// and returns the paths to the private and public keys respectively.
|
||||
// The file paths are deterministic from the clusterName.
|
||||
func CreateSSHKeyPair(clusterName string) (string, string, error) {
|
||||
_, privateKey, err := ed25519.GenerateKey(nil)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
publicKey, err := ssh.NewPublicKey(privateKey.Public())
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
publicKeyContents := ssh.MarshalAuthorizedKey(publicKey)
|
||||
|
||||
user := os.Getenv("USER")
|
||||
if user == "" {
|
||||
user = "user"
|
||||
}
|
||||
comment := fmt.Sprintf(" %v\n", user)
|
||||
|
||||
// AWS requires a comment on the SSH public key but MarshalAuthorizedKey doesn't create one
|
||||
publicKeyContents = publicKeyContents[:len(publicKeyContents)-1]
|
||||
publicKeyContents = append(publicKeyContents, []byte(comment)...)
|
||||
|
||||
privateKeyContents, err := x509.MarshalPKCS8PrivateKey(privateKey)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
tmp := os.TempDir()
|
||||
dir := filepath.Join(tmp, "kops", clusterName)
|
||||
err = os.MkdirAll(dir, 0700)
|
||||
if err != nil {
|
||||
if err := os.MkdirAll(dir, 0700); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
publicKeyPath := filepath.Join(dir, "id_ed25519.pub")
|
||||
privateKeyPath := filepath.Join(dir, "id_ed25519")
|
||||
publicKeyPath := filepath.Join(dir, "id_ed25519.pub")
|
||||
|
||||
if _, err := os.Stat(privateKeyPath); errors.Is(err, os.ErrNotExist) {
|
||||
if err := os.WriteFile(publicKeyPath, publicKeyContents, 0644); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
f, err := os.OpenFile(privateKeyPath, os.O_WRONLY|os.O_CREATE, 0600)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
err = pem.Encode(f, &pem.Block{
|
||||
Type: "PRIVATE KEY",
|
||||
Bytes: privateKeyContents,
|
||||
})
|
||||
if err != nil {
|
||||
cmd := exec.Command("ssh-keygen", "-t", "ed25519", "-N", "", "-q", "-f", privateKeyPath)
|
||||
exec.InheritOutput(cmd)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue