master
1package generate
2
3import (
4 "crypto"
5 "crypto/ed25519"
6 "encoding/base64"
7 "encoding/pem"
8 "fmt"
9 "os"
10 "path/filepath"
11
12 "golang.org/x/crypto/ssh"
13)
14
15// helpers
16func writeStringToFile(filePath string, data string, permission os.FileMode) error {
17 file, err := os.Create(filePath)
18 if err != nil {
19 return fmt.Errorf("failed to create file %s: %w", filePath, err)
20 }
21
22 if _, err = file.WriteString(data); err != nil {
23 return fmt.Errorf("failed to write to file %s: %w", filePath, err)
24 }
25
26 if err = file.Chmod(permission); err != nil {
27 return fmt.Errorf("failed to change file permissions: %w", err)
28 }
29
30 return nil
31}
32
33func returnKeyPath(fileName string) (string, error) {
34 currentDir, err := os.Getwd()
35 if err != nil {
36 return "", fmt.Errorf("failed to get current directory: %w", err)
37 }
38
39 keyPath := filepath.Join(currentDir, fileName)
40
41 return keyPath, nil
42}
43
44// main
45func generateSSHKeyEDSA() (string, string, error) {
46 // Generate a new Ed25519 private key
47 //// If rand is nil, crypto/rand.Reader will be used
48 public, private, err := ed25519.GenerateKey(nil)
49 if err != nil {
50 return "", "", fmt.Errorf("failed to generate ed25519 key: %w", err)
51 }
52
53 // public key
54 publicKey, err := ssh.NewPublicKey(public)
55 if err != nil {
56 return "", "", fmt.Errorf("failed to create public key: %w", err)
57 }
58 publicKeyString := fmt.Sprintf("ssh-ed25519 %s", base64.StdEncoding.EncodeToString(publicKey.Marshal()))
59
60 // private key
61 //// p stands for pem
62 p, err := ssh.MarshalPrivateKey(crypto.PrivateKey(private), "")
63 if err != nil {
64 return "", "", fmt.Errorf("failed to marshal private key: %w", err)
65 }
66 privateKeyPem := pem.EncodeToMemory(p)
67 privateKeyString := string(privateKeyPem)
68
69 return publicKeyString, privateKeyString, nil
70}
71
72func SSHKey(args []string) error {
73 //init
74 if len(args) == 0 {
75 return fmt.Errorf("please specify key name")
76 }
77
78 // main
79 publicKeyString, privateKeyString, err := generateSSHKeyEDSA()
80 if err != nil {
81 return err
82 }
83
84 // write key to file
85 publicKeyFilename := fmt.Sprintf("%s.pub", args[0])
86 if err = writeStringToFile(publicKeyFilename, publicKeyString, 0644); err != nil {
87 return err
88 }
89
90 privateKeyFilename := args[0]
91 if err = writeStringToFile(privateKeyFilename, privateKeyString, 0600); err != nil {
92 return err
93 }
94
95 keyPath, err := returnKeyPath(args[0])
96 if err != nil {
97 return err
98 }
99
100 fmt.Printf("SSH key created at: %s\n", keyPath)
101 return nil
102}