aboutsummaryrefslogtreecommitdiff
path: root/ssh/example_test.go
diff options
context:
space:
mode:
authorNicola Murino <nicola.murino@gmail.com>2025-05-04 14:40:10 +0200
committerGopher Robot <gobot@golang.org>2025-05-15 10:43:30 -0700
commitac58737d259962f38068acb1bcd4a51850ec4951 (patch)
treeb142269653a486b4d644cdd18acb16832437552b /ssh/example_test.go
parent9dbbcf002b5cbae3b65a93e406438711bef52e53 (diff)
downloadgo-x-crypto-ac58737d259962f38068acb1bcd4a51850ec4951.tar.xz
ssh: export supported algorithms
Fixes golang/go#61537 Change-Id: If3478121e3ae445391e3faeceeb889d75e9e3214 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/531935 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Nicola Murino <nicola.murino@gmail.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Filippo Valsorda <filippo@golang.org>
Diffstat (limited to 'ssh/example_test.go')
-rw-r--r--ssh/example_test.go110
1 files changed, 110 insertions, 0 deletions
diff --git a/ssh/example_test.go b/ssh/example_test.go
index 97b3b6a..d6bad3e 100644
--- a/ssh/example_test.go
+++ b/ssh/example_test.go
@@ -154,6 +154,75 @@ func ExampleNewServerConn() {
}
}
+func ExampleServerConfig() {
+ // Minimal ServerConfig with SHA-1 algoritms disabled and supporting only
+ // public key authentication.
+
+ // The algorithms returned by ssh.SupportedAlgorithms() are different from
+ // the default ones and do not include algorithms that are considered
+ // insecure, such as those using SHA-1, returned by
+ // ssh.InsecureAlgorithms().
+ algorithms := ssh.SupportedAlgorithms()
+
+ // Public key authentication is done by comparing
+ // the public key of a received connection
+ // with the entries in the authorized_keys file.
+ authorizedKeysBytes, err := os.ReadFile("authorized_keys")
+ if err != nil {
+ log.Fatalf("Failed to load authorized_keys, err: %v", err)
+ }
+
+ authorizedKeysMap := map[string]bool{}
+ for len(authorizedKeysBytes) > 0 {
+ pubKey, _, _, rest, err := ssh.ParseAuthorizedKey(authorizedKeysBytes)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ authorizedKeysMap[string(pubKey.Marshal())] = true
+ authorizedKeysBytes = rest
+ }
+
+ config := &ssh.ServerConfig{
+ Config: ssh.Config{
+ KeyExchanges: algorithms.KeyExchanges,
+ Ciphers: algorithms.Ciphers,
+ MACs: algorithms.MACs,
+ },
+ // The configured PublicKeyAuthAlgorithms do not contain SHA-1 based
+ // signature formats, so if the client attempts to use them the
+ // authentication will fail before calling the defined callback.
+ PublicKeyAuthAlgorithms: algorithms.PublicKeyAuths,
+ PublicKeyCallback: func(c ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) {
+ if authorizedKeysMap[string(pubKey.Marshal())] {
+ return &ssh.Permissions{
+ // Record the public key used for authentication.
+ Extensions: map[string]string{
+ "pubkey-fp": ssh.FingerprintSHA256(pubKey),
+ },
+ }, nil
+ }
+ return nil, fmt.Errorf("unknown public key for %q", c.User())
+ },
+ }
+
+ privateBytes, err := os.ReadFile("id_rsa")
+ if err != nil {
+ log.Fatal("Failed to load private key: ", err)
+ }
+
+ private, err := ssh.ParsePrivateKey(privateBytes)
+ if err != nil {
+ log.Fatal("Failed to parse private key: ", err)
+ }
+ // Restrict host key algorithms to disable ssh-rsa.
+ signer, err := ssh.NewSignerWithAlgorithms(private.(ssh.AlgorithmSigner), []string{ssh.KeyAlgoRSASHA256, ssh.KeyAlgoRSASHA512})
+ if err != nil {
+ log.Fatal("Failed to create private key with restricted algorithms: ", err)
+ }
+ config.AddHostKey(signer)
+}
+
func ExampleServerConfig_AddHostKey() {
// Minimal ServerConfig supporting only password authentication.
config := &ssh.ServerConfig{
@@ -262,6 +331,47 @@ func ExampleDial() {
fmt.Println(b.String())
}
+func ExampleClientConfig() {
+ var hostKey ssh.PublicKey
+ key, err := os.ReadFile("/home/user/.ssh/id_rsa")
+ if err != nil {
+ log.Fatalf("unable to read private key: %v", err)
+ }
+
+ // Create the Signer for this private key.
+ signer, err := ssh.ParsePrivateKey(key)
+ if err != nil {
+ log.Fatalf("unable to parse private key: %v", err)
+ }
+
+ // Minimal ClientConfig with SHA-1 algoritms disabled.
+ // The algorithms returned by ssh.SupportedAlgorithms() are different from
+ // the default ones and do not include algorithms that are considered
+ // insecure, such as those using SHA-1, returned by
+ // ssh.InsecureAlgorithms().
+ algorithms := ssh.SupportedAlgorithms()
+ config := &ssh.ClientConfig{
+ Config: ssh.Config{
+ KeyExchanges: algorithms.KeyExchanges,
+ Ciphers: algorithms.Ciphers,
+ MACs: algorithms.MACs,
+ },
+ User: "username",
+ Auth: []ssh.AuthMethod{
+ ssh.PublicKeys(signer),
+ },
+ HostKeyCallback: ssh.FixedHostKey(hostKey),
+ // We should check that hostKey algorithm is inlcuded in
+ // algorithms.HostKeys.
+ HostKeyAlgorithms: algorithms.HostKeys,
+ }
+ client, err := ssh.Dial("tcp", "yourserver.com:22", config)
+ if err != nil {
+ log.Fatal("Failed to dial: ", err)
+ }
+ defer client.Close()
+}
+
func ExamplePublicKeys() {
var hostKey ssh.PublicKey
// A public key may be used to authenticate against the remote