diff --git a/ssh-manager/generate_ecdsa.go b/ssh-manager/generate_ecdsa.go index 36de9b3..e5d859f 100644 --- a/ssh-manager/generate_ecdsa.go +++ b/ssh-manager/generate_ecdsa.go @@ -9,18 +9,25 @@ import ( "fmt" ) +// GenerateEcdsa creates a new ECDSA SSH key pair. func (m *SshManager) GenerateEcdsa( ctx context.Context, + // The remote host address (e.g., github.com). remoteHost string, + // The user name on the remote host. remoteUser string, + // The hostname of the local machine used for key naming. // +optional // +default="dagger" localHostname string, + // The bit size for the ECDSA curve (256, 384, or 521). // +optional // +default=521 bits int, + // Automatically generate a 32-character passphrase for the private key. // +optional autoPassphrase bool, + // An existing SSH config file to append the new configuration to. // +optional existingConfig *dagger.File, ) (*KeyResult, error) { @@ -33,7 +40,7 @@ func (m *SshManager) GenerateEcdsa( case 521: curve = elliptic.P521() default: - return nil, fmt.Errorf("invalid bits for ecdsa") + return nil, fmt.Errorf("invalid bits for ecdsa: must be 256, 384, or 521") } priv, err := ecdsa.GenerateKey(curve, rand.Reader) if err != nil { diff --git a/ssh-manager/generate_ed25519.go b/ssh-manager/generate_ed25519.go index 4aadc88..946c9d7 100644 --- a/ssh-manager/generate_ed25519.go +++ b/ssh-manager/generate_ed25519.go @@ -7,15 +7,21 @@ import ( "dagger/ssh-manager/internal/dagger" ) +// GenerateEd25519 creates a new Ed25519 SSH key pair. This is the recommended modern algorithm. func (m *SshManager) GenerateEd25519( ctx context.Context, + // The remote host address (e.g., github.com). remoteHost string, + // The user name on the remote host. remoteUser string, + // The hostname of the local machine used for key naming. // +optional // +default="dagger" localHostname string, + // Automatically generate a 32-character passphrase for the private key. // +optional autoPassphrase bool, + // An existing SSH config file to append the new configuration to. // +optional existingConfig *dagger.File, ) (*KeyResult, error) { diff --git a/ssh-manager/main.go b/ssh-manager/main.go index f43ac29..940f877 100644 --- a/ssh-manager/main.go +++ b/ssh-manager/main.go @@ -1,3 +1,4 @@ +// SSH Manager module for generating secure SSH key pairs and configurations. package main import ( @@ -15,89 +16,22 @@ import ( "golang.org/x/crypto/ssh" ) -type SshManager struct{} +// SshManager provides services to generate and manage SSH identities. +type SshManager struct{} //revive:disable-line +// KeyResult represents the collection of generated SSH components. type KeyResult struct { - PublicKey *dagger.File `json:"publicKey"` - PrivateKey *dagger.Secret `json:"privateKey"` - Config *dagger.File `json:"config"` - Files *dagger.Directory `json:"files"` + // The OpenSSH formatted public key file. + PublicKey *dagger.File `json:"publicKey"` + // The OpenSSH formatted private key, stored as a secret. + PrivateKey *dagger.Secret `json:"privateKey"` + // The SSH configuration file containing host and proxy settings. + Config *dagger.File `json:"config"` + // A directory containing the private key, public key, and config for easy export. + Files *dagger.Directory `json:"files"` } -// func (m *SshManager) GenerateRsa( -// ctx context.Context, -// remoteHost string, -// remoteUser string, -// // +optional -// // +default="dagger" -// localHostname string, -// // +optional -// // +default=4096 -// bits int, -// // +optional -// autoPassphrase bool, -// // +optional -// existingConfig *dagger.File, -// ) (*KeyResult, error) { -// priv, err := rsa.GenerateKey(rand.Reader, bits) -// if err != nil { -// return nil, err -// } -// return m.finalize(ctx, priv, priv.Public(), "rsa", remoteHost, remoteUser, localHostname, autoPassphrase, existingConfig) -// } - -/* func (m *SshManager) GenerateEd25519( - ctx context.Context, - remoteHost string, - remoteUser string, - // +optional - // +default="dagger" - localHostname string, - // +optional - autoPassphrase bool, - // +optional - existingConfig *dagger.File, -) (*KeyResult, error) { - pub, priv, err := ed25519.GenerateKey(rand.Reader) - if err != nil { - return nil, err - } - return m.finalize(ctx, priv, pub, "ed25519", remoteHost, remoteUser, localHostname, autoPassphrase, existingConfig) -} */ - -// func (m *SshManager) GenerateEcdsa( -// ctx context.Context, -// remoteHost string, -// remoteUser string, -// // +optional -// // +default="dagger" -// localHostname string, -// // +optional -// // +default=521 -// bits int, -// // +optional -// autoPassphrase bool, -// // +optional -// existingConfig *dagger.File, -// ) (*KeyResult, error) { -// var curve elliptic.Curve -// switch bits { -// case 256: -// curve = elliptic.P256() -// case 384: -// curve = elliptic.P384() -// case 521: -// curve = elliptic.P521() -// default: -// return nil, fmt.Errorf("invalid bits for ecdsa") -// } -// priv, err := ecdsa.GenerateKey(curve, rand.Reader) -// if err != nil { -// return nil, err -// } -// return m.finalize(ctx, priv, priv.Public(), "ecdsa", remoteHost, remoteUser, localHostname, autoPassphrase, existingConfig) -// } - +// finalize is an internal helper to process raw keys into formatted files and secrets. func (m *SshManager) finalize( ctx context.Context, priv any, @@ -169,6 +103,7 @@ func (m *SshManager) finalize( }, nil } +// randomString generates a cryptographically secure random string for passphrases. func (m *SshManager) randomString(n int) string { const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()" ret := make([]byte, n) diff --git a/ssh-manager/rsa.go b/ssh-manager/rsa.go index e916733..9bb4fec 100644 --- a/ssh-manager/rsa.go +++ b/ssh-manager/rsa.go @@ -7,18 +7,25 @@ import ( "dagger/ssh-manager/internal/dagger" ) +// GenerateRsa creates a new RSA SSH key pair. func (m *SshManager) GenerateRsa( ctx context.Context, + // The remote host address (e.g., github.com). remoteHost string, + // The user name on the remote host. remoteUser string, + // The hostname of the local machine used for key naming. // +optional // +default="dagger" localHostname string, + // The bit length for the RSA key. // +optional // +default=4096 bits int, + // Automatically generate a 32-character passphrase for the private key. // +optional autoPassphrase bool, + // An existing SSH config file to append the new configuration to. // +optional existingConfig *dagger.File, ) (*KeyResult, error) { diff --git a/ssh-manager/test/main.go b/ssh-manager/test/main.go index 53222c5..b0e0532 100644 --- a/ssh-manager/test/main.go +++ b/ssh-manager/test/main.go @@ -11,7 +11,6 @@ // The first line in this comment block is a short description line and the // rest is a long description with more detail on the module's purpose or usage, // if appropriate. All modules should have a short description. - package main import ( @@ -23,7 +22,7 @@ import ( "github.com/sourcegraph/conc/pool" ) -type SshManagertest struct{} +type SshManagertest struct{} //revive:disable-line // All runs all SSH key generation tests in parallel. func (m *SshManagertest) All(ctx context.Context) error {