// Insert adds a private key to the keyring. If a certificate // is given, that certificate is added as public key. Note that // any constraints given are ignored. func (r *keyring) Add(key AddedKey) error { r.mu.Lock() defer r.mu.Unlock() if r.locked { return errLocked } signer, err := ssh.NewSignerFromKey(key.PrivateKey) if err != nil { return err } if cert := key.Certificate; cert != nil { signer, err = ssh.NewCertSigner(cert, signer) if err != nil { return err } } p := privKey{ signer: signer, comment: key.Comment, } if key.LifetimeSecs > 0 { t := time.Now().Add(time.Duration(key.LifetimeSecs) * time.Second) p.expire = &t } r.keys = append(r.keys, p) return nil }
func TestCertLogin(t *testing.T) { s := newServer(t) defer s.Shutdown() // Use a key different from the default. clientKey := testSigners["dsa"] caAuthKey := testSigners["ecdsa"] cert := &ssh.Certificate{ Key: clientKey.PublicKey(), ValidPrincipals: []string{username()}, CertType: ssh.UserCert, ValidBefore: ssh.CertTimeInfinity, } if err := cert.SignCert(rand.Reader, caAuthKey); err != nil { t.Fatalf("SetSignature: %v", err) } certSigner, err := ssh.NewCertSigner(cert, clientKey) if err != nil { t.Fatalf("NewCertSigner: %v", err) } conf := &ssh.ClientConfig{ User: username(), } conf.Auth = append(conf.Auth, ssh.PublicKeys(certSigner)) client, err := s.TryDial(conf) if err != nil { t.Fatalf("TryDial: %v", err) } client.Close() }
func init() { var err error n := len(testdata.PEMBytes) testPrivateKeys = make(map[string]interface{}, n) testSigners = make(map[string]ssh.Signer, n) testPublicKeys = make(map[string]ssh.PublicKey, n) for t, k := range testdata.PEMBytes { testPrivateKeys[t], err = ssh.ParseRawPrivateKey(k) if err != nil { panic(fmt.Sprintf("Unable to parse test key %s: %v", t, err)) } testSigners[t], err = ssh.NewSignerFromKey(testPrivateKeys[t]) if err != nil { panic(fmt.Sprintf("Unable to create signer for test key %s: %v", t, err)) } testPublicKeys[t] = testSigners[t].PublicKey() } // Create a cert and sign it for use in tests. testCert := &ssh.Certificate{ Nonce: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil ValidPrincipals: []string{"gopher1", "gopher2"}, // increases test coverage ValidAfter: 0, // unix epoch ValidBefore: ssh.CertTimeInfinity, // The end of currently representable time. Reserved: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil Key: testPublicKeys["ecdsa"], SignatureKey: testPublicKeys["rsa"], Permissions: ssh.Permissions{ CriticalOptions: map[string]string{}, Extensions: map[string]string{}, }, } testCert.SignCert(rand.Reader, testSigners["rsa"]) testPrivateKeys["cert"] = testPrivateKeys["ecdsa"] testSigners["cert"], err = ssh.NewCertSigner(testCert, testSigners["ecdsa"]) if err != nil { panic(fmt.Sprintf("Unable to create certificate signer: %v", err)) } }
// Insert adds a private key to the keyring. If a certificate // is given, that certificate is added as public key. func (r *keyring) Add(priv interface{}, cert *ssh.Certificate, comment string) error { r.mu.Lock() defer r.mu.Unlock() if r.locked { return errLocked } signer, err := ssh.NewSignerFromKey(priv) if err != nil { return err } if cert != nil { signer, err = ssh.NewCertSigner(cert, signer) if err != nil { return err } } r.keys = append(r.keys, privKey{signer, comment}) return nil }
// Insert adds a private key to the keyring. If a certificate // is given, that certificate is added as public key. Note that // any constraints given are ignored. func (r *keyring) Add(key AddedKey) error { r.mu.Lock() defer r.mu.Unlock() if r.locked { return errLocked } signer, err := ssh.NewSignerFromKey(key.PrivateKey) if err != nil { return err } if cert := key.Certificate; cert != nil { signer, err = ssh.NewCertSigner(cert, signer) if err != nil { return err } } r.keys = append(r.keys, privKey{signer, key.Comment}) return nil }
func NewGateway(serverVersion string, caPublicKey, hostCertificate, hostPrivateKey []byte) (*Gateway, error) { // parse certificate authority ca, _, _, _, err := ssh.ParseAuthorizedKey(caPublicKey) if err != nil { return nil, err } glog.V(9).Infof("auth: ca_public_key = %v", ca) // parse host certificate parsed, _, _, _, err := ssh.ParseAuthorizedKey(hostCertificate) if err != nil { return nil, err } cert, ok := parsed.(*ssh.Certificate) if !ok { return nil, ErrInvalidCertificate } principal := "localhost" if len(cert.ValidPrincipals) > 0 { principal = cert.ValidPrincipals[0] } // parse host key key, err := ssh.ParsePrivateKey(hostPrivateKey) if err != nil { return nil, err } // create signer for host host, err := ssh.NewCertSigner(cert, key) if err != nil { return nil, err } glog.V(9).Infof("auth: host_public_key = %v", key.PublicKey()) // create checker // TODO: implement IsRevoked checker := &ssh.CertChecker{ IsAuthority: func(key ssh.PublicKey) bool { if bytes.Compare(ca.Marshal(), key.Marshal()) == 0 { return true } glog.V(9).Infof("auth: unknown authority: %v", key) return false }, IsRevoked: func(cert *ssh.Certificate) bool { return false }, } // test the checker glog.V(9).Infof("auth: testing host certificate using principal: %s", principal) if err := checker.CheckCert(principal, cert); err != nil { return nil, err } // create server config config := &ssh.ServerConfig{ PublicKeyCallback: func(meta ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { glog.V(9).Infof("auth: remote = %s, local = %s, public_key = %v", meta.RemoteAddr(), meta.LocalAddr(), key) return checker.Authenticate(meta, key) }, AuthLogCallback: func(meta ssh.ConnMetadata, method string, err error) { glog.V(2).Infof("auth: remote = %s, local = %s, method = %s, error = %v", meta.RemoteAddr(), meta.LocalAddr(), method, err) }, ServerVersion: serverVersion, } config.AddHostKey(host) return &Gateway{ config: config, sessionsIndex: make(map[string][]*Session), sessionsList: make([]*Session, 0), lock: &sync.Mutex{}, }, nil }