|
@@ -6,10 +6,15 @@ package ssh
|
|
|
|
|
|
|
|
import (
|
|
import (
|
|
|
"bytes"
|
|
"bytes"
|
|
|
|
|
+ "crypto/ecdsa"
|
|
|
|
|
+ "crypto/elliptic"
|
|
|
"crypto/rand"
|
|
"crypto/rand"
|
|
|
|
|
+ "net"
|
|
|
"reflect"
|
|
"reflect"
|
|
|
"testing"
|
|
"testing"
|
|
|
"time"
|
|
"time"
|
|
|
|
|
+
|
|
|
|
|
+ "golang.org/x/crypto/ssh/testdata"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
// Cert generated by ssh-keygen 6.0p1 Debian-4.
|
|
// Cert generated by ssh-keygen 6.0p1 Debian-4.
|
|
@@ -220,3 +225,111 @@ func TestHostKeyCert(t *testing.T) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+func TestCertTypes(t *testing.T) {
|
|
|
|
|
+ var testVars = []struct {
|
|
|
|
|
+ name string
|
|
|
|
|
+ keys func() Signer
|
|
|
|
|
+ }{
|
|
|
|
|
+ {
|
|
|
|
|
+ name: CertAlgoECDSA256v01,
|
|
|
|
|
+ keys: func() Signer {
|
|
|
|
|
+ s, _ := ParsePrivateKey(testdata.PEMBytes["ecdsap256"])
|
|
|
|
|
+ return s
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ name: CertAlgoECDSA384v01,
|
|
|
|
|
+ keys: func() Signer {
|
|
|
|
|
+ s, _ := ParsePrivateKey(testdata.PEMBytes["ecdsap384"])
|
|
|
|
|
+ return s
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ name: CertAlgoECDSA521v01,
|
|
|
|
|
+ keys: func() Signer {
|
|
|
|
|
+ s, _ := ParsePrivateKey(testdata.PEMBytes["ecdsap521"])
|
|
|
|
|
+ return s
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ name: CertAlgoED25519v01,
|
|
|
|
|
+ keys: func() Signer {
|
|
|
|
|
+ s, _ := ParsePrivateKey(testdata.PEMBytes["ed25519"])
|
|
|
|
|
+ return s
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ name: CertAlgoRSAv01,
|
|
|
|
|
+ keys: func() Signer {
|
|
|
|
|
+ s, _ := ParsePrivateKey(testdata.PEMBytes["rsa"])
|
|
|
|
|
+ return s
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ name: CertAlgoDSAv01,
|
|
|
|
|
+ keys: func() Signer {
|
|
|
|
|
+ s, _ := ParsePrivateKey(testdata.PEMBytes["dsa"])
|
|
|
|
|
+ return s
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Fatalf("error generating host key: %v", err)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ signer, err := NewSignerFromKey(k)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Fatalf("error generating signer for ssh listener: %v", err)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ conf := &ServerConfig{
|
|
|
|
|
+ PublicKeyCallback: func(c ConnMetadata, k PublicKey) (*Permissions, error) {
|
|
|
|
|
+ return new(Permissions), nil
|
|
|
|
|
+ },
|
|
|
|
|
+ }
|
|
|
|
|
+ conf.AddHostKey(signer)
|
|
|
|
|
+
|
|
|
|
|
+ for _, m := range testVars {
|
|
|
|
|
+ t.Run(m.name, func(t *testing.T) {
|
|
|
|
|
+
|
|
|
|
|
+ c1, c2, err := netPipe()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Fatalf("netPipe: %v", err)
|
|
|
|
|
+ }
|
|
|
|
|
+ defer c1.Close()
|
|
|
|
|
+ defer c2.Close()
|
|
|
|
|
+
|
|
|
|
|
+ go NewServerConn(c1, conf)
|
|
|
|
|
+
|
|
|
|
|
+ priv := m.keys()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Fatalf("error generating ssh pubkey: %v", err)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ cert := &Certificate{
|
|
|
|
|
+ CertType: UserCert,
|
|
|
|
|
+ Key: priv.PublicKey(),
|
|
|
|
|
+ }
|
|
|
|
|
+ cert.SignCert(rand.Reader, priv)
|
|
|
|
|
+
|
|
|
|
|
+ certSigner, err := NewCertSigner(cert, priv)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Fatalf("error generating cert signer: %v", err)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ config := &ClientConfig{
|
|
|
|
|
+ User: "user",
|
|
|
|
|
+ HostKeyCallback: func(h string, r net.Addr, k PublicKey) error { return nil },
|
|
|
|
|
+ Auth: []AuthMethod{PublicKeys(certSigner)},
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ _, _, _, err = NewClientConn(c2, "", config)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Fatalf("error connecting: %v", err)
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+}
|