From 42f28ab8e374137fe3f5d25424489d879d4724f8 Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Wed, 21 Jun 2017 19:06:17 -0700 Subject: Updating server dependancies (#6712) --- vendor/golang.org/x/crypto/ssh/certs.go | 24 ++++++----- vendor/golang.org/x/crypto/ssh/certs_test.go | 24 +++++++---- vendor/golang.org/x/crypto/ssh/connection.go | 2 +- vendor/golang.org/x/crypto/ssh/example_test.go | 11 ++++- vendor/golang.org/x/crypto/ssh/kex.go | 8 ++-- vendor/golang.org/x/crypto/ssh/keys.go | 43 +++++++++++++++++++ vendor/golang.org/x/crypto/ssh/keys_test.go | 19 +++++++++ vendor/golang.org/x/crypto/ssh/server.go | 48 ++++++++++++++-------- vendor/golang.org/x/crypto/ssh/test/cert_test.go | 41 +++++++++++++++--- .../golang.org/x/crypto/ssh/test/test_unix_test.go | 19 ++++++++- vendor/golang.org/x/crypto/ssh/testdata/keys.go | 41 ++++++++++++++++++ 11 files changed, 230 insertions(+), 50 deletions(-) (limited to 'vendor/golang.org/x/crypto/ssh') diff --git a/vendor/golang.org/x/crypto/ssh/certs.go b/vendor/golang.org/x/crypto/ssh/certs.go index 2fc8af1b1..b1f022078 100644 --- a/vendor/golang.org/x/crypto/ssh/certs.go +++ b/vendor/golang.org/x/crypto/ssh/certs.go @@ -298,8 +298,17 @@ func (c *CertChecker) CheckHostKey(addr string, remote net.Addr, key PublicKey) if cert.CertType != HostCert { return fmt.Errorf("ssh: certificate presented as a host key has type %d", cert.CertType) } + if !c.IsHostAuthority(cert.SignatureKey, addr) { + return fmt.Errorf("ssh: no authorities for hostname: %v", addr) + } + + hostname, _, err := net.SplitHostPort(addr) + if err != nil { + return err + } - return c.CheckCert(addr, cert) + // Pass hostname only as principal for host certificates (consistent with OpenSSH) + return c.CheckCert(hostname, cert) } // Authenticate checks a user certificate. Authenticate can be used as @@ -316,6 +325,9 @@ func (c *CertChecker) Authenticate(conn ConnMetadata, pubKey PublicKey) (*Permis if cert.CertType != UserCert { return nil, fmt.Errorf("ssh: cert has type %d", cert.CertType) } + if !c.IsUserAuthority(cert.SignatureKey) { + return nil, fmt.Errorf("ssh: certificate signed by unrecognized authority") + } if err := c.CheckCert(conn.User(), cert); err != nil { return nil, err @@ -364,16 +376,6 @@ func (c *CertChecker) CheckCert(principal string, cert *Certificate) error { } } - // if this is a host cert, principal is the remote hostname as passed - // to CheckHostCert. - if cert.CertType == HostCert && !c.IsHostAuthority(cert.SignatureKey, principal) { - return fmt.Errorf("ssh: no authorities for hostname: %v", principal) - } - - if cert.CertType == UserCert && !c.IsUserAuthority(cert.SignatureKey) { - return fmt.Errorf("ssh: certificate signed by unrecognized authority") - } - clock := c.Clock if clock == nil { clock = time.Now diff --git a/vendor/golang.org/x/crypto/ssh/certs_test.go b/vendor/golang.org/x/crypto/ssh/certs_test.go index fba6310c5..0200531f4 100644 --- a/vendor/golang.org/x/crypto/ssh/certs_test.go +++ b/vendor/golang.org/x/crypto/ssh/certs_test.go @@ -168,8 +168,8 @@ func TestHostKeyCert(t *testing.T) { cert.SignCert(rand.Reader, testSigners["ecdsa"]) checker := &CertChecker{ - IsHostAuthority: func(p PublicKey, h string) bool { - return h == "hostname" && bytes.Equal(testPublicKeys["ecdsa"].Marshal(), p.Marshal()) + IsHostAuthority: func(p PublicKey, addr string) bool { + return addr == "hostname:22" && bytes.Equal(testPublicKeys["ecdsa"].Marshal(), p.Marshal()) }, } @@ -178,7 +178,14 @@ func TestHostKeyCert(t *testing.T) { t.Errorf("NewCertSigner: %v", err) } - for _, name := range []string{"hostname", "otherhost", "lasthost"} { + for _, test := range []struct { + addr string + succeed bool + }{ + {addr: "hostname:22", succeed: true}, + {addr: "otherhost:22", succeed: false}, // The certificate is valid for 'otherhost' as hostname, but we only recognize the authority of the signer for the address 'hostname:22' + {addr: "lasthost:22", succeed: false}, + } { c1, c2, err := netPipe() if err != nil { t.Fatalf("netPipe: %v", err) @@ -201,16 +208,15 @@ func TestHostKeyCert(t *testing.T) { User: "user", HostKeyCallback: checker.CheckHostKey, } - _, _, _, err = NewClientConn(c2, name, config) + _, _, _, err = NewClientConn(c2, test.addr, config) - succeed := name == "hostname" - if (err == nil) != succeed { - t.Fatalf("NewClientConn(%q): %v", name, err) + if (err == nil) != test.succeed { + t.Fatalf("NewClientConn(%q): %v", test.addr, err) } err = <-errc - if (err == nil) != succeed { - t.Fatalf("NewServerConn(%q): %v", name, err) + if (err == nil) != test.succeed { + t.Fatalf("NewServerConn(%q): %v", test.addr, err) } } } diff --git a/vendor/golang.org/x/crypto/ssh/connection.go b/vendor/golang.org/x/crypto/ssh/connection.go index e786f2f9a..fd6b0681b 100644 --- a/vendor/golang.org/x/crypto/ssh/connection.go +++ b/vendor/golang.org/x/crypto/ssh/connection.go @@ -25,7 +25,7 @@ type ConnMetadata interface { // User returns the user ID for this connection. User() string - // SessionID returns the sesson hash, also denoted by H. + // SessionID returns the session hash, also denoted by H. SessionID() []byte // ClientVersion returns the client's version string as hashed diff --git a/vendor/golang.org/x/crypto/ssh/example_test.go b/vendor/golang.org/x/crypto/ssh/example_test.go index 618398cea..b910c7bf6 100644 --- a/vendor/golang.org/x/crypto/ssh/example_test.go +++ b/vendor/golang.org/x/crypto/ssh/example_test.go @@ -56,7 +56,12 @@ func ExampleNewServerConn() { // Remove to disable public key auth. PublicKeyCallback: func(c ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) { if authorizedKeysMap[string(pubKey.Marshal())] { - return nil, nil + 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()) }, @@ -87,10 +92,12 @@ func ExampleNewServerConn() { // Before use, a handshake must be performed on the incoming // net.Conn. - _, chans, reqs, err := ssh.NewServerConn(nConn, config) + conn, chans, reqs, err := ssh.NewServerConn(nConn, config) if err != nil { log.Fatal("failed to handshake: ", err) } + log.Printf("logged in with key %s", conn.Permissions.Extensions["pubkey-fp"]) + // The incoming Request channel must be serviced. go ssh.DiscardRequests(reqs) diff --git a/vendor/golang.org/x/crypto/ssh/kex.go b/vendor/golang.org/x/crypto/ssh/kex.go index c87fbebfd..f91c2770e 100644 --- a/vendor/golang.org/x/crypto/ssh/kex.go +++ b/vendor/golang.org/x/crypto/ssh/kex.go @@ -383,8 +383,8 @@ func init() { // 4253 and Oakley Group 2 in RFC 2409. p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF", 16) kexAlgoMap[kexAlgoDH1SHA1] = &dhGroup{ - g: new(big.Int).SetInt64(2), - p: p, + g: new(big.Int).SetInt64(2), + p: p, pMinus1: new(big.Int).Sub(p, bigOne), } @@ -393,8 +393,8 @@ func init() { p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16) kexAlgoMap[kexAlgoDH14SHA1] = &dhGroup{ - g: new(big.Int).SetInt64(2), - p: p, + g: new(big.Int).SetInt64(2), + p: p, pMinus1: new(big.Int).Sub(p, bigOne), } diff --git a/vendor/golang.org/x/crypto/ssh/keys.go b/vendor/golang.org/x/crypto/ssh/keys.go index cf6853232..4c8b1a8f7 100644 --- a/vendor/golang.org/x/crypto/ssh/keys.go +++ b/vendor/golang.org/x/crypto/ssh/keys.go @@ -756,6 +756,18 @@ func ParsePrivateKey(pemBytes []byte) (Signer, error) { return NewSignerFromKey(key) } +// ParsePrivateKeyWithPassphrase returns a Signer from a PEM encoded private +// key and passphrase. It supports the same keys as +// ParseRawPrivateKeyWithPassphrase. +func ParsePrivateKeyWithPassphrase(pemBytes, passPhrase []byte) (Signer, error) { + key, err := ParseRawPrivateKeyWithPassphrase(pemBytes, passPhrase) + if err != nil { + return nil, err + } + + return NewSignerFromKey(key) +} + // encryptedBlock tells whether a private key is // encrypted by examining its Proc-Type header // for a mention of ENCRYPTED @@ -790,6 +802,37 @@ func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) { } } +func ParseRawPrivateKeyWithPassphrase(pemBytes, passPhrase []byte) (interface{}, error) { + block, _ := pem.Decode(pemBytes) + if block == nil { + return nil, errors.New("ssh: no key found") + } + buf := block.Bytes + + if encryptedBlock(block) { + if x509.IsEncryptedPEMBlock(block) { + var err error + buf, err = x509.DecryptPEMBlock(block, passPhrase) + if err != nil { + return nil, fmt.Errorf("ssh: cannot decode encrypted private keys: %v", err) + } + } + } + + switch block.Type { + case "RSA PRIVATE KEY": + return x509.ParsePKCS1PrivateKey(buf) + case "EC PRIVATE KEY": + return x509.ParseECPrivateKey(buf) + case "DSA PRIVATE KEY": + return ParseDSAPrivateKey(buf) + case "OPENSSH PRIVATE KEY": + return parseOpenSSHPrivateKey(buf) + default: + return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type) + } +} + // ParseDSAPrivateKey returns a DSA private key from its ASN.1 DER encoding, as // specified by the OpenSSL DSA man page. func ParseDSAPrivateKey(der []byte) (*dsa.PrivateKey, error) { diff --git a/vendor/golang.org/x/crypto/ssh/keys_test.go b/vendor/golang.org/x/crypto/ssh/keys_test.go index a65e87e53..2bacc52ae 100644 --- a/vendor/golang.org/x/crypto/ssh/keys_test.go +++ b/vendor/golang.org/x/crypto/ssh/keys_test.go @@ -148,6 +148,25 @@ func TestParseEncryptedPrivateKeysFails(t *testing.T) { } } +// Parse encrypted private keys with passphrase +func TestParseEncryptedPrivateKeysWithPassphrase(t *testing.T) { + data := []byte("sign me") + for _, tt := range testdata.PEMEncryptedKeys { + s, err := ParsePrivateKeyWithPassphrase(tt.PEMBytes, []byte(tt.EncryptionKey)) + if err != nil { + t.Fatalf("ParsePrivateKeyWithPassphrase returned error: %s", err) + continue + } + sig, err := s.Sign(rand.Reader, data) + if err != nil { + t.Fatalf("dsa.Sign: %v", err) + } + if err := s.PublicKey().Verify(data, sig); err != nil { + t.Errorf("Verify failed: %v", err) + } + } +} + func TestParseDSA(t *testing.T) { // We actually exercise the ParsePrivateKey codepath here, as opposed to // using the ParseRawPrivateKey+NewSignerFromKey path that testdata_test.go diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go index 23b41d943..70d6077dc 100644 --- a/vendor/golang.org/x/crypto/ssh/server.go +++ b/vendor/golang.org/x/crypto/ssh/server.go @@ -14,23 +14,34 @@ import ( ) // The Permissions type holds fine-grained permissions that are -// specific to a user or a specific authentication method for a -// user. Permissions, except for "source-address", must be enforced in -// the server application layer, after successful authentication. The -// Permissions are passed on in ServerConn so a server implementation -// can honor them. +// specific to a user or a specific authentication method for a user. +// The Permissions value for a successful authentication attempt is +// available in ServerConn, so it can be used to pass information from +// the user-authentication phase to the application layer. type Permissions struct { - // Critical options restrict default permissions. Common - // restrictions are "source-address" and "force-command". If - // the server cannot enforce the restriction, or does not - // recognize it, the user should not authenticate. + // CriticalOptions indicate restrictions to the default + // permissions, and are typically used in conjunction with + // user certificates. The standard for SSH certificates + // defines "force-command" (only allow the given command to + // execute) and "source-address" (only allow connections from + // the given address). The SSH package currently only enforces + // the "source-address" critical option. It is up to server + // implementations to enforce other critical options, such as + // "force-command", by checking them after the SSH handshake + // is successful. In general, SSH servers should reject + // connections that specify critical options that are unknown + // or not supported. CriticalOptions map[string]string // Extensions are extra functionality that the server may - // offer on authenticated connections. Common extensions are - // "permit-agent-forwarding", "permit-X11-forwarding". Lack of - // support for an extension does not preclude authenticating a - // user. + // offer on authenticated connections. Lack of support for an + // extension does not preclude authenticating a user. Common + // extensions are "permit-agent-forwarding", + // "permit-X11-forwarding". The Go SSH library currently does + // not act on any extension, and it is up to server + // implementations to honor them. Extensions can be used to + // pass data from the authentication callbacks to the server + // application layer. Extensions map[string]string } @@ -55,9 +66,14 @@ type ServerConfig struct { // attempts to authenticate using a password. PasswordCallback func(conn ConnMetadata, password []byte) (*Permissions, error) - // PublicKeyCallback, if non-nil, is called when a client attempts public - // key authentication. It must return true if the given public key is - // valid for the given user. For example, see CertChecker.Authenticate. + // PublicKeyCallback, if non-nil, is called when a client + // offers a public key for authentication. It must return true + // if the given public key can be used to authenticate the + // given user. For example, see CertChecker.Authenticate. A + // call to this function does not guarantee that the key + // offered is in fact used to authenticate. To record any data + // depending on the public key, store it inside a + // Permissions.Extensions entry. PublicKeyCallback func(conn ConnMetadata, key PublicKey) (*Permissions, error) // KeyboardInteractiveCallback, if non-nil, is called when diff --git a/vendor/golang.org/x/crypto/ssh/test/cert_test.go b/vendor/golang.org/x/crypto/ssh/test/cert_test.go index bc83e4f5d..b231dd80c 100644 --- a/vendor/golang.org/x/crypto/ssh/test/cert_test.go +++ b/vendor/golang.org/x/crypto/ssh/test/cert_test.go @@ -7,12 +7,14 @@ package test import ( + "bytes" "crypto/rand" "testing" "golang.org/x/crypto/ssh" ) +// Test both logging in with a cert, and also that the certificate presented by an OpenSSH host can be validated correctly func TestCertLogin(t *testing.T) { s := newServer(t) defer s.Shutdown() @@ -36,13 +38,40 @@ func TestCertLogin(t *testing.T) { } conf := &ssh.ClientConfig{ - User: username(), - HostKeyCallback: ssh.InsecureIgnoreHostKey(), + User: username(), + HostKeyCallback: (&ssh.CertChecker{ + IsHostAuthority: func(pk ssh.PublicKey, addr string) bool { + return bytes.Equal(pk.Marshal(), testPublicKeys["ca"].Marshal()) + }, + }).CheckHostKey, } conf.Auth = append(conf.Auth, ssh.PublicKeys(certSigner)) - client, err := s.TryDial(conf) - if err != nil { - t.Fatalf("TryDial: %v", err) + + for _, test := range []struct { + addr string + succeed bool + }{ + {addr: "host.example.com:22", succeed: true}, + {addr: "host.example.com:10000", succeed: true}, // non-standard port must be OK + {addr: "host.example.com", succeed: false}, // port must be specified + {addr: "host.ex4mple.com:22", succeed: false}, // wrong host + } { + client, err := s.TryDialWithAddr(conf, test.addr) + + // Always close client if opened successfully + if err == nil { + client.Close() + } + + // Now evaluate whether the test failed or passed + if test.succeed { + if err != nil { + t.Fatalf("TryDialWithAddr: %v", err) + } + } else { + if err == nil { + t.Fatalf("TryDialWithAddr, unexpected success") + } + } } - client.Close() } diff --git a/vendor/golang.org/x/crypto/ssh/test/test_unix_test.go b/vendor/golang.org/x/crypto/ssh/test/test_unix_test.go index dd9ff4003..e673536a8 100644 --- a/vendor/golang.org/x/crypto/ssh/test/test_unix_test.go +++ b/vendor/golang.org/x/crypto/ssh/test/test_unix_test.go @@ -30,6 +30,7 @@ Protocol 2 HostKey {{.Dir}}/id_rsa HostKey {{.Dir}}/id_dsa HostKey {{.Dir}}/id_ecdsa +HostCertificate {{.Dir}}/id_rsa-cert.pub Pidfile {{.Dir}}/sshd.pid #UsePrivilegeSeparation no KeyRegenerationInterval 3600 @@ -119,6 +120,11 @@ func clientConfig() *ssh.ClientConfig { ssh.PublicKeys(testSigners["user"]), }, HostKeyCallback: hostKeyDB().Check, + HostKeyAlgorithms: []string{ // by default, don't allow certs as this affects the hostKeyDB checker + ssh.KeyAlgoECDSA256, ssh.KeyAlgoECDSA384, ssh.KeyAlgoECDSA521, + ssh.KeyAlgoRSA, ssh.KeyAlgoDSA, + ssh.KeyAlgoED25519, + }, } return config } @@ -154,6 +160,12 @@ func unixConnection() (*net.UnixConn, *net.UnixConn, error) { } func (s *server) TryDial(config *ssh.ClientConfig) (*ssh.Client, error) { + return s.TryDialWithAddr(config, "") +} + +// addr is the user specified host:port. While we don't actually dial it, +// we need to know this for host key matching +func (s *server) TryDialWithAddr(config *ssh.ClientConfig, addr string) (*ssh.Client, error) { sshd, err := exec.LookPath("sshd") if err != nil { s.t.Skipf("skipping test: %v", err) @@ -179,7 +191,7 @@ func (s *server) TryDial(config *ssh.ClientConfig) (*ssh.Client, error) { s.t.Fatalf("s.cmd.Start: %v", err) } s.clientConn = c1 - conn, chans, reqs, err := ssh.NewClientConn(c1, "", config) + conn, chans, reqs, err := ssh.NewClientConn(c1, addr, config) if err != nil { return nil, err } @@ -250,6 +262,11 @@ func newServer(t *testing.T) *server { writeFile(filepath.Join(dir, filename+".pub"), ssh.MarshalAuthorizedKey(testPublicKeys[k])) } + for k, v := range testdata.SSHCertificates { + filename := "id_" + k + "-cert.pub" + writeFile(filepath.Join(dir, filename), v) + } + var authkeys bytes.Buffer for k, _ := range testdata.PEMBytes { authkeys.Write(ssh.MarshalAuthorizedKey(testPublicKeys[k])) diff --git a/vendor/golang.org/x/crypto/ssh/testdata/keys.go b/vendor/golang.org/x/crypto/ssh/testdata/keys.go index 0be2e7e65..3b3d26c5b 100644 --- a/vendor/golang.org/x/crypto/ssh/testdata/keys.go +++ b/vendor/golang.org/x/crypto/ssh/testdata/keys.go @@ -69,6 +69,47 @@ MHcCAQEEILYCAeq8f7V4vSSypRw7pxy8yz3V5W4qg8kSC3zJhqpQoAoGCCqGSM49 AwEHoUQDQgAEYcO2xNKiRUYOLEHM7VYAp57HNyKbOdYtHD83Z4hzNPVC4tM5mdGD PLL8IEwvYu2wq+lpXfGQnNMbzYf9gspG0w== -----END EC PRIVATE KEY----- +`), + "ca": []byte(`-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAvg9dQ9IRG59lYJb+GESfKWTch4yBpr7Ydw1jkK6vvtrx9jLo +5hkA8X6+ElRPRqTAZSlN5cBm6YCAcQIOsmXDUn6Oj1lVPQAoOjTBTvsjM3NjGhvv +52kHTY0nsMsBeY9q5DTtlzmlYkVUq2a6Htgf2mNi01dIw5fJ7uTTo8EbNf7O0i3u +c9a8P19HaZl5NKiWN4EIZkfB2WdXYRJCVBsGgQj3dE/GrEmH9QINq1A+GkNvK96u +vZm8H1jjmuqzHplWa7lFeXcx8FTVTbVb/iJrZ2Lc/JvIPitKZWhqbR59yrGjpwEp +Id7bo4WhO5L3OB0fSIJYvfu+o4WYnt4f3UzecwIDAQABAoIBABRD9yHgKErVuC2Q +bA+SYZY8VvdtF/X7q4EmQFORDNRA7EPgMc03JU6awRGbQ8i4kHs46EFzPoXvWcKz +AXYsO6N0Myc900Tp22A5d9NAHATEbPC/wdje7hRq1KyZONMJY9BphFv3nZbY5apR +Dc90JBFZP5RhXjTc3n9GjvqLAKfFEKVmPRCvqxCOZunw6XR+SgIQLJo36nsIsbhW +QUXIVaCI6cXMN8bRPm8EITdBNZu06Fpu4ZHm6VaxlXN9smERCDkgBSNXNWHKxmmA +c3Glo2DByUr2/JFBOrLEe9fkYgr24KNCQkHVcSaFxEcZvTggr7StjKISVHlCNEaB +7Q+kPoECgYEA3zE9FmvFGoQCU4g4Nl3dpQHs6kaAW8vJlrmq3xsireIuaJoa2HMe +wYdIvgCnK9DIjyxd5OWnE4jXtAEYPsyGD32B5rSLQrRO96lgb3f4bESCLUb3Bsn/ +sdgeE3p1xZMA0B59htqCrvVgN9k8WxyevBxYl3/gSBm/p8OVH1RTW/ECgYEA2f9Z +95OLj0KQHQtxQXf+I3VjhCw3LkLW39QZOXVI0QrCJfqqP7uxsJXH9NYX0l0GFTcR +kRrlyoaSU1EGQosZh+n1MvplGBTkTSV47/bPsTzFpgK2NfEZuFm9RoWgltS+nYeH +Y2k4mnAN3PhReCMwuprmJz8GRLsO3Cs2s2YylKMCgYEA2UX+uO/q7jgqZ5UJW+ue +1H5+W0aMuFA3i7JtZEnvRaUVFqFGlwXin/WJ2+WY1++k/rPrJ+Rk9IBXtBUIvEGw +FC5TIfsKQsJyyWgqx/jbbtJ2g4s8+W/1qfTAuqeRNOg5d2DnRDs90wJuS4//0JaY +9HkHyVwkQyxFxhSA/AHEMJECgYA2MvyFR1O9bIk0D3I7GsA+xKLXa77Ua53MzIjw +9i4CezBGDQpjCiFli/fI8am+jY5DnAtsDknvjoG24UAzLy5L0mk6IXMdB6SzYYut +7ak5oahqW+Y9hxIj+XvLmtGQbphtxhJtLu35x75KoBpxSh6FZpmuTEccs31AVCYn +eFM/DQKBgQDOPUwbLKqVi6ddFGgrV9MrWw+SWsDa43bPuyvYppMM3oqesvyaX1Dt +qDvN7owaNxNM4OnfKcZr91z8YPVCFo4RbBif3DXRzjNNBlxEjHBtuMOikwvsmucN +vIrbeEpjTiUMTEAr6PoTiVHjsfS8WAM6MDlF5M+2PNswDsBpa2yLgA== +-----END RSA PRIVATE KEY----- +`), +} + +var SSHCertificates = map[string][]byte{ + // The following are corresponding certificates for the private keys above, signed by the CA key + // Generated by the following commands: + // + // 1. Assumes "rsa" key above in file named "rsa", write out the public key to "rsa.pub": + // ssh-keygen -y -f rsa > rsa.pu + // + // 2. Assumes "ca" key above in file named "ca", sign a cert for "rsa.pub": + // ssh-keygen -s ca -h -n host.example.com -V +500w -I host.example.com-key rsa.pub + "rsa": []byte(`ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgLjYqmmuTSEmjVhSfLQphBSTJMLwIZhRgmpn8FHKLiEIAAAADAQABAAAAgQC8A6FGHDiWCSREAXCq6yBfNVr0xCVG2CzvktFNRpue+RXrGs/2a6ySEJQb3IYquw7HlJgu6fg3WIWhOmHCjfpG0PrL4CRwbqQ2LaPPXhJErWYejcD8Di00cF3677+G10KMZk9RXbmHtuBFZT98wxg8j+ZsBMqGM1+7yrWUvynswQAAAAAAAAAAAAAAAgAAABRob3N0LmV4YW1wbGUuY29tLWtleQAAABQAAAAQaG9zdC5leGFtcGxlLmNvbQAAAABZHN8UAAAAAGsjIYUAAAAAAAAAAAAAAAAAAAEXAAAAB3NzaC1yc2EAAAADAQABAAABAQC+D11D0hEbn2Vglv4YRJ8pZNyHjIGmvth3DWOQrq++2vH2MujmGQDxfr4SVE9GpMBlKU3lwGbpgIBxAg6yZcNSfo6PWVU9ACg6NMFO+yMzc2MaG+/naQdNjSewywF5j2rkNO2XOaViRVSrZroe2B/aY2LTV0jDl8nu5NOjwRs1/s7SLe5z1rw/X0dpmXk0qJY3gQhmR8HZZ1dhEkJUGwaBCPd0T8asSYf1Ag2rUD4aQ28r3q69mbwfWOOa6rMemVZruUV5dzHwVNVNtVv+ImtnYtz8m8g+K0plaGptHn3KsaOnASkh3tujhaE7kvc4HR9Igli9+76jhZie3h/dTN5zAAABDwAAAAdzc2gtcnNhAAABALeDea+60H6xJGhktAyosHaSY7AYzLocaqd8hJQjEIDifBwzoTlnBmcK9CxGhKuaoJFThdCLdaevCeOSuquh8HTkf+2ebZZc/G5T+2thPvPqmcuEcmMosWo+SIjYhbP3S6KD49aLC1X0kz8IBQeauFvURhkZ5ZjhA1L4aQYt9NjL73nqOl8PplRui+Ov5w8b4ldul4zOvYAFrzfcP6wnnXk3c1Zzwwf5wynD5jakO8GpYKBuhM7Z4crzkKSQjU3hla7xqgfomC5Gz4XbR2TNjcQiRrJQ0UlKtX3X3ObRCEhuvG0Kzjklhv+Ddw6txrhKjMjiSi/Yyius/AE8TmC1p4U= host.example.com `), } -- cgit v1.2.3-1-g7c22