(parentDir string)
| 36 | } |
| 37 | |
| 38 | func LoadOrGenerateRSAHostKey(parentDir string) (ssh.Signer, bool) { |
| 39 | privateKeyPath := filepath.Join(parentDir, "ssh_host_rsa_key") |
| 40 | publicKeyPath := filepath.Join(parentDir, "ssh_host_rsa_key.pub") |
| 41 | privateKeyBytes, err := os.ReadFile(privateKeyPath) |
| 42 | if err == nil { |
| 43 | var privateKey *rsa.PrivateKey |
| 44 | privateKey, err = rsaDecodePrivateKey(privateKeyBytes) |
| 45 | if err == nil { |
| 46 | var ret ssh.Signer |
| 47 | ret, err = ssh.NewSignerFromKey(privateKey) |
| 48 | if err == nil { |
| 49 | return ret, true |
| 50 | } |
| 51 | } |
| 52 | } |
| 53 | _ = os.Remove(privateKeyPath) |
| 54 | _ = os.Remove(publicKeyPath) |
| 55 | privateKey, err := rsa.GenerateKey(rand.Reader, 4096) |
| 56 | if err != nil { |
| 57 | utils.Log.Errorf("failed to generate RSA private key: %+v", err) |
| 58 | return nil, false |
| 59 | } |
| 60 | publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey) |
| 61 | if err != nil { |
| 62 | utils.Log.Errorf("failed to generate RSA public key: %+v", err) |
| 63 | return nil, false |
| 64 | } |
| 65 | ret, err := ssh.NewSignerFromKey(privateKey) |
| 66 | if err != nil { |
| 67 | utils.Log.Errorf("failed to generate RSA signer: %+v", err) |
| 68 | return nil, false |
| 69 | } |
| 70 | privateBytes := rsaEncodePrivateKey(privateKey) |
| 71 | publicBytes := ssh.MarshalAuthorizedKey(publicKey) |
| 72 | err = os.WriteFile(privateKeyPath, privateBytes, 0600) |
| 73 | if err != nil { |
| 74 | utils.Log.Errorf("failed to write RSA private key to file: %+v", err) |
| 75 | return nil, false |
| 76 | } |
| 77 | err = os.WriteFile(publicKeyPath, publicBytes, 0644) |
| 78 | if err != nil { |
| 79 | _ = os.Remove(privateKeyPath) |
| 80 | utils.Log.Errorf("failed to write RSA public key to file: %+v", err) |
| 81 | return nil, false |
| 82 | } |
| 83 | return ret, true |
| 84 | } |
| 85 | |
| 86 | func rsaEncodePrivateKey(privateKey *rsa.PrivateKey) []byte { |
| 87 | privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) |
no test coverage detected