func ReadIdentityFromKeyPair(keyBytes, certBytes []byte) (*Identity, error) {
	if len(keyBytes) == 0 {
		return nil, trace.BadParameter("PrivateKey: missing private key")
	}

	if len(certBytes) == 0 {
		return nil, trace.BadParameter("Cert: missing parameter")
	}

	pubKey, _, _, _, err := ssh.ParseAuthorizedKey(certBytes)
	if err != nil {
		return nil, trace.BadParameter("failed to parse server certificate: %v", err)
	}

	cert, ok := pubKey.(*ssh.Certificate)
	if !ok {
		return nil, trace.BadParameter("expected ssh.Certificate, got %v", pubKey)
	}

	signer, err := ssh.ParsePrivateKey(keyBytes)
	if err != nil {
		return nil, trace.BadParameter("failed to parse private key: %v", err)
	}
	// this signer authenticates using certificate signed by the cert authority
	// not only by the public key
	certSigner, err := ssh.NewCertSigner(cert, signer)
	if err != nil {
		return nil, trace.BadParameter("unsupported private key: %v", err)
	}
	if len(cert.ValidPrincipals) != 1 {
		return nil, trace.BadParameter("valid principals: need exactly 1 valid principal: host uuid")
	}

	if len(cert.Permissions.Extensions) == 0 {
		return nil, trace.BadParameter("extensions: misssing needed extensions for host roles")
	}
	roleString := cert.Permissions.Extensions[utils.CertExtensionRole]
	if roleString == "" {
		return nil, trace.BadParameter("misssing cert extension %v", utils.CertExtensionRole)
	}
	roles, err := teleport.ParseRoles(roleString)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	foundRoles := len(roles)
	if foundRoles != 1 {
		return nil, trace.Errorf("expected one role per certificate. found %d: '%s'",
			foundRoles, roles.String())
	}
	role := roles[0]
	authorityDomain := cert.Permissions.Extensions[utils.CertExtensionAuthority]
	if authorityDomain == "" {
		return nil, trace.BadParameter("misssing cert extension %v", utils.CertExtensionAuthority)
	}

	if cert.ValidPrincipals[0] == "" {
		return nil, trace.BadParameter("valid principal can not be empty")
	}

	return &Identity{
		ID:              IdentityID{HostUUID: cert.ValidPrincipals[0], Role: role},
		AuthorityDomain: authorityDomain,
		KeyBytes:        keyBytes,
		CertBytes:       certBytes,
		KeySigner:       certSigner,
		Cert:            cert,
	}, nil
}
// ReadIdentityFromKeyPair reads identity from initialized keypair
ReadIdentityFromKeyPair reads identity from initialized keypair
// ReadIdentityFromKeyPair reads identity from initialized keypair
func ReadIdentityFromKeyPair(keyBytes, certBytes []byte) (*Identity, error) {
	if len(keyBytes) == 0 {
		return nil, trace.BadParameter("PrivateKey: missing private key")
	}
	if len(certBytes) == 0 {
		return nil, trace.BadParameter("Cert: missing parameter")
	}
	pubKey, _, _, _, err := ssh.ParseAuthorizedKey(certBytes)
	if err != nil {
		return nil, trace.BadParameter("failed to parse server certificate: %v", err)
	}
	cert, ok := pubKey.(*ssh.Certificate)
	if !ok {
		return nil, trace.BadParameter("expected ssh.Certificate, got %v", pubKey)
	}
	signer, err := ssh.ParsePrivateKey(keyBytes)
	if err != nil {
		return nil, trace.BadParameter("failed to parse private key: %v", err)
	}
	certSigner, err := ssh.NewCertSigner(cert, signer)
	if err != nil {
		return nil, trace.BadParameter("unsupported private key: %v", err)
	}
	if len(cert.ValidPrincipals) != 1 {
		return nil, trace.BadParameter("valid principals: need exactly 1 valid principal: host uuid")
	}
	if len(cert.Permissions.Extensions) == 0 {
		return nil, trace.BadParameter("extensions: misssing needed extensions for host roles")
	}
	roleString := cert.Permissions.Extensions[utils.CertExtensionRole]
	if roleString == "" {
		return nil, trace.BadParameter("misssing cert extension %v", utils.CertExtensionRole)
	}
	roles, err := teleport.ParseRoles(roleString)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	foundRoles := len(roles)
	if foundRoles != 1 {
		return nil, trace.Errorf("expected one role per certificate. found %d: '%s'",
			foundRoles, roles.String())
	}
	role := roles[0]
	authorityDomain := cert.Permissions.Extensions[utils.CertExtensionAuthority]
	if authorityDomain == "" {
		return nil, trace.BadParameter("misssing cert extension %v", utils.CertExtensionAuthority)
	}
	if cert.ValidPrincipals[0] == "" {
		return nil, trace.BadParameter("valid principal can not be empty")
	}
	return &Identity{
		ID:              IdentityID{HostUUID: cert.ValidPrincipals[0], Role: role},
		AuthorityDomain: authorityDomain,
		KeyBytes:        keyBytes,
		CertBytes:       certBytes,
		KeySigner:       certSigner,
		Cert:            cert,
	}, nil
}
func ReadIdentityFromKeyPair ( keyBytes , certBytes [ ] byte ) ( * Identity , error ) { if len ( keyBytes ) == 0 { return nil , trace . BadParameter ( " " ) } if len ( certBytes ) == 0 { return nil , trace . BadParameter ( " " ) } pubKey , _ , _ , _ , err := ssh . ParseAuthorizedKey ( certBytes ) if err != nil { return nil , trace . BadParameter ( " " , err ) } cert , ok := pubKey . ( * ssh . Certificate ) if ! ok { return nil , trace . BadParameter ( " " , pubKey ) } signer , err := ssh . ParsePrivateKey ( keyBytes ) if err != nil { return nil , trace . BadParameter ( " " , err ) } certSigner , err := ssh . NewCertSigner ( cert , signer ) if err != nil { return nil , trace . BadParameter ( " " , err ) } if len ( cert . ValidPrincipals ) != 1 { return nil , trace . BadParameter ( " " ) } if len ( cert . Permissions . Extensions ) == 0 { return nil , trace . BadParameter ( " " ) } roleString := cert . Permissions . Extensions [ utils . CertExtensionRole ] if roleString == " " { return nil , trace . BadParameter ( " " , utils . CertExtensionRole ) } roles , err := teleport . ParseRoles ( roleString ) if err != nil { return nil , trace . Wrap ( err ) } foundRoles := len ( roles ) if foundRoles != 1 { return nil , trace . Errorf ( " " , foundRoles , roles . String ( ) ) } role := roles [ 0 ] authorityDomain := cert . Permissions . Extensions [ utils . CertExtensionAuthority ] if authorityDomain == " " { return nil , trace . BadParameter ( " " , utils . CertExtensionAuthority ) } if cert . ValidPrincipals [ 0 ] == " " { return nil , trace . BadParameter ( " " ) } return & Identity { ID : IdentityID { HostUUID : cert . ValidPrincipals [ 0 ] , Role : role } , AuthorityDomain : authorityDomain , KeyBytes : keyBytes , CertBytes : certBytes , KeySigner : certSigner , Cert : cert , } , nil }
ReadIdentityFromKeyPair reads identity from initialized keypair
ReadIdentityFromKeyPair reads identity from initialized keypair
// this signer authenticates using certificate signed by the cert authority // not only by the public key