ssh: add MultiAlgorithmSigner
MultiAlgorithmSigner allows to restrict client-side, server-side and certificate signing algorithms. Fixes golang/go#52132 Fixes golang/go#36261 Change-Id: I295092f1bba647327aaaf294f110e9157d294159 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/508398 Reviewed-by: Filippo Valsorda <filippo@golang.org> Run-TryBot: Filippo Valsorda <filippo@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com> Auto-Submit: Filippo Valsorda <filippo@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
committed by
Gopher Robot
parent
3f0842a464
commit
28c53ff63c
+67
-1
@@ -7,6 +7,8 @@ package ssh_test
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
@@ -75,7 +77,6 @@ func ExampleNewServerConn() {
|
||||
if err != nil {
|
||||
log.Fatal("Failed to parse private key: ", err)
|
||||
}
|
||||
|
||||
config.AddHostKey(private)
|
||||
|
||||
// Once a ServerConfig has been configured, connections can be
|
||||
@@ -139,6 +140,36 @@ func ExampleNewServerConn() {
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleServerConfig_AddHostKey() {
|
||||
// Minimal ServerConfig supporting only password authentication.
|
||||
config := &ssh.ServerConfig{
|
||||
PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
|
||||
// Should use constant-time compare (or better, salt+hash) in
|
||||
// a production setting.
|
||||
if c.User() == "testuser" && string(pass) == "tiger" {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("password rejected 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 ExampleClientConfig_HostKeyCallback() {
|
||||
// Every client must provide a host key check. Here is a
|
||||
// simple-minded parse of OpenSSH's known_hosts file
|
||||
@@ -318,3 +349,38 @@ func ExampleSession_RequestPty() {
|
||||
log.Fatal("failed to start shell: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleCertificate_SignCert() {
|
||||
// Sign a certificate with a specific algorithm.
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 3072)
|
||||
if err != nil {
|
||||
log.Fatal("unable to generate RSA key: ", err)
|
||||
}
|
||||
publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey)
|
||||
if err != nil {
|
||||
log.Fatal("unable to get RSA public key: ", err)
|
||||
}
|
||||
caKey, err := rsa.GenerateKey(rand.Reader, 3072)
|
||||
if err != nil {
|
||||
log.Fatal("unable to generate CA key: ", err)
|
||||
}
|
||||
signer, err := ssh.NewSignerFromKey(caKey)
|
||||
if err != nil {
|
||||
log.Fatal("unable to generate signer from key: ", err)
|
||||
}
|
||||
mas, err := ssh.NewSignerWithAlgorithms(signer.(ssh.AlgorithmSigner), []string{ssh.KeyAlgoRSASHA256})
|
||||
if err != nil {
|
||||
log.Fatal("unable to create signer with algoritms: ", err)
|
||||
}
|
||||
certificate := ssh.Certificate{
|
||||
Key: publicKey,
|
||||
CertType: ssh.UserCert,
|
||||
}
|
||||
if err := certificate.SignCert(rand.Reader, mas); err != nil {
|
||||
log.Fatal("unable to sign certificate: ", err)
|
||||
}
|
||||
// Save the public key to a file and check that rsa-sha-256 is used for
|
||||
// signing:
|
||||
// ssh-keygen -L -f <path to the file>
|
||||
fmt.Println(string(ssh.MarshalAuthorizedKey(&certificate)))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user