Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eliminate GenerateRSAKeyRing #47244

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions lib/client/conntest/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,9 @@ func (s *KubeConnectionTester) TestConnection(ctx context.Context, req TestConne
// genKubeRestTLSClientConfig creates the Teleport user credentials to access
// the given Kubernetes cluster name.
func (s KubeConnectionTester) genKubeRestTLSClientConfig(ctx context.Context, mfaResponse *proto.MFAAuthenticateResponse, connectionDiagnosticID, clusterName, userName string) (rest.TLSClientConfig, error) {
// TODO(nklaassen): support configurable key algorithms.
key, err := cryptosuites.GenerateKeyWithAlgorithm(cryptosuites.RSA2048)
key, err := cryptosuites.GenerateKey(ctx,
cryptosuites.GetCurrentSuiteFromAuthPreference(s.cfg.UserClient),
cryptosuites.UserTLS)
if err != nil {
return rest.TLSClientConfig{}, trace.Wrap(err)
}
Expand Down
12 changes: 10 additions & 2 deletions lib/client/conntest/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ import (
"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/constants"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/utils/keys"
"github.com/gravitational/teleport/api/utils/sshutils"
"github.com/gravitational/teleport/lib/auth/authclient"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/connectmycomputer"
"github.com/gravitational/teleport/lib/cryptosuites"
libsshutils "github.com/gravitational/teleport/lib/sshutils"
)

Expand Down Expand Up @@ -106,11 +108,17 @@ func (s *SSHConnectionTester) TestConnection(ctx context.Context, req TestConnec
return nil, trace.Wrap(err)
}

// TODO(nklaassen): support configurable keyRing algorithms.
keyRing, err := client.GenerateRSAKeyRing()
key, err := cryptosuites.GenerateKey(ctx,
cryptosuites.GetCurrentSuiteFromAuthPreference(s.cfg.UserClient),
cryptosuites.UserSSH)
if err != nil {
return nil, trace.Wrap(err)
}
privateKey, err := keys.NewSoftwarePrivateKey(key)
if err != nil {
return nil, trace.Wrap(err)
}
keyRing := client.NewKeyRing(privateKey, privateKey)

tlsPub, err := keyRing.TLSPrivateKey.MarshalTLSPublicKey()
if err != nil {
Expand Down
14 changes: 11 additions & 3 deletions lib/client/db/database_certificates.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ import (

"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/utils/keys"
"github.com/gravitational/teleport/lib/auth/authclient"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/client/identityfile"
"github.com/gravitational/teleport/lib/cryptosuites"
"github.com/gravitational/teleport/lib/services"
"github.com/gravitational/teleport/lib/tlsca"
)
Expand All @@ -38,6 +40,7 @@ type CertificateSigner interface {
GetClusterName(opts ...services.MarshalOption) (types.ClusterName, error)
GetCertAuthority(ctx context.Context, id types.CertAuthID, loadKeys bool) (types.CertAuthority, error)
GenerateDatabaseCert(context.Context, *proto.DatabaseCertRequest) (*proto.DatabaseCertResponse, error)
Ping(context.Context) (proto.PingResponse, error)
}

// GenerateDatabaseCertificatesRequest contains the required fields used to generate database certificates
Expand Down Expand Up @@ -94,12 +97,17 @@ func GenerateDatabaseServerCertificates(ctx context.Context, req GenerateDatabas
}

if req.KeyRing == nil {
// TODO(nklaassen): don't hardcode RSA here.
keyRing, err := client.GenerateRSAKeyRing()
key, err := cryptosuites.GenerateKey(ctx,
cryptosuites.GetCurrentSuiteFromPing(req.ClusterAPI),
cryptosuites.DatabaseServer)
if err != nil {
return nil, trace.Wrap(err)
}
req.KeyRing = keyRing
privateKey, err := keys.NewSoftwarePrivateKey(key)
if err != nil {
return nil, trace.Wrap(err)
}
req.KeyRing = client.NewKeyRing(privateKey, privateKey)
}

csr, err := tlsca.GenerateCertificateRequestPEM(subject, req.KeyRing.TLSPrivateKey)
Expand Down
12 changes: 0 additions & 12 deletions lib/client/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ import (
"github.com/gravitational/teleport/api/utils/keys"
"github.com/gravitational/teleport/api/utils/sshutils"
"github.com/gravitational/teleport/lib/auth/authclient"
"github.com/gravitational/teleport/lib/auth/native"
"github.com/gravitational/teleport/lib/cryptosuites"
"github.com/gravitational/teleport/lib/services"
"github.com/gravitational/teleport/lib/tlsca"
Expand Down Expand Up @@ -161,17 +160,6 @@ func (k *KeyRing) generateSubjectTLSKey(ctx context.Context, tc *TeleportClient,
return priv, nil
}

// GenerateRSAKeyRing generates a new unsigned RSA key ring.
//
// TODO(nklaassen): get away from hardcoding RSA here.
func GenerateRSAKeyRing() (*KeyRing, error) {
priv, err := native.GeneratePrivateKey()
if err != nil {
return nil, trace.Wrap(err)
}
return NewKeyRing(priv, priv), nil
}

// NewKeyRing creates a new KeyRing for the given private keys.
func NewKeyRing(sshPriv, tlsPriv *keys.PrivateKey) *KeyRing {
return &KeyRing{
Expand Down
26 changes: 26 additions & 0 deletions lib/cryptosuites/suites.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (

"github.com/gravitational/trace"

"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/auth/native"
)
Expand Down Expand Up @@ -89,6 +90,8 @@ const (

// DatabaseClient represents a key used for a database client.
DatabaseClient
// DatabaseServer represents a key used for a database server.
DatabaseServer

// HostSSH represents a host SSH key.
HostSSH
Expand Down Expand Up @@ -166,6 +169,7 @@ var (
UserSSH: RSA2048,
UserTLS: RSA2048,
DatabaseClient: RSA2048,
DatabaseServer: RSA2048,
HostSSH: RSA2048,
HostIdentity: RSA2048,
BotImpersonatedIdentity: RSA2048,
Expand Down Expand Up @@ -198,6 +202,7 @@ var (
UserSSH: Ed25519,
UserTLS: ECDSAP256,
DatabaseClient: RSA2048,
DatabaseServer: RSA2048,
HostSSH: Ed25519,
HostIdentity: ECDSAP256,
BotImpersonatedIdentity: ECDSAP256,
Expand Down Expand Up @@ -227,6 +232,7 @@ var (
UserSSH: ECDSAP256,
UserTLS: ECDSAP256,
DatabaseClient: RSA2048,
DatabaseServer: RSA2048,
HostSSH: ECDSAP256,
HostIdentity: ECDSAP256,
BotImpersonatedIdentity: ECDSAP256,
Expand Down Expand Up @@ -258,6 +264,7 @@ var (
UserSSH: Ed25519,
UserTLS: ECDSAP256,
DatabaseClient: RSA2048,
DatabaseServer: RSA2048,
HostSSH: Ed25519,
HostIdentity: ECDSAP256,
BotImpersonatedIdentity: ECDSAP256,
Expand Down Expand Up @@ -294,6 +301,25 @@ func GetCurrentSuiteFromAuthPreference(authPrefGetter AuthPreferenceGetter) GetS
})
}

// Pinger is an interface for pinging the auth server.
type Pinger interface {
// Ping returns a Ping response containing the current signature algorithm
// suite.
Ping(context.Context) (proto.PingResponse, error)
}

// GetCurrentSuiteFromPing returns a [GetSuiteFunc] that fetches the signature
// algorithm suite currently configured in the cluster via the ping endpoint.
func GetCurrentSuiteFromPing(pinger Pinger) GetSuiteFunc {
return GetSuiteFunc(func(ctx context.Context) (types.SignatureAlgorithmSuite, error) {
pingResp, err := pinger.Ping(ctx)
if err != nil {
return types.SignatureAlgorithmSuite_SIGNATURE_ALGORITHM_SUITE_UNSPECIFIED, trace.Wrap(err)
}
return pingResp.SignatureAlgorithmSuite, nil
})
}

// GetSuiteFunc is a function type that retrieves the current signature
// algorithm suite configured in the cluster.
type GetSuiteFunc func(context.Context) (types.SignatureAlgorithmSuite, error)
Expand Down
22 changes: 9 additions & 13 deletions tool/tctl/common/auth_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,9 @@ func (a *AuthCommand) ExportAuthorities(ctx context.Context, clt *authclient.Cli

// GenerateKeys generates a new keypair
func (a *AuthCommand) GenerateKeys(ctx context.Context, clusterAPI certificateSigner) error {
signer, err := cryptosuites.GenerateKey(ctx, getCurrentSuiteFromPing(clusterAPI), cryptosuites.UserSSH)
signer, err := cryptosuites.GenerateKey(ctx,
cryptosuites.GetCurrentSuiteFromPing(clusterAPI),
cryptosuites.UserSSH)
if err != nil {
return trace.Wrap(err)
}
Expand Down Expand Up @@ -502,7 +504,9 @@ func (a *AuthCommand) generateHostKeys(ctx context.Context, clusterAPI certifica
principals := strings.Split(a.genHost, ",")

// Generate an SSH key.
signer, err := cryptosuites.GenerateKey(ctx, getCurrentSuiteFromPing(clusterAPI), cryptosuites.HostSSH)
signer, err := cryptosuites.GenerateKey(ctx,
cryptosuites.GetCurrentSuiteFromPing(clusterAPI),
cryptosuites.HostSSH)
if err != nil {
return trace.Wrap(err)
}
Expand Down Expand Up @@ -853,24 +857,16 @@ client_encryption_options:
`))
)

func getCurrentSuiteFromPing(clusterAPI certificateSigner) cryptosuites.GetSuiteFunc {
return func(ctx context.Context) (types.SignatureAlgorithmSuite, error) {
pr, err := clusterAPI.Ping(ctx)
if err != nil {
return types.SignatureAlgorithmSuite_SIGNATURE_ALGORITHM_SUITE_UNSPECIFIED, trace.Wrap(err)
}
return pr.SignatureAlgorithmSuite, nil
}
}

// generateKeyRing generates and returns a keyring using a key algorithm
// determined by the current cluster signature algorithm suite and [purpose].
// The returned KeyRing always uses a single private key for both SSH and TLS,
// this is a deliberate choice for `tctl auth sign` which either only uses a
// single protocol anyway, or writes to an identity file which only supports a
// single private key.
func generateKeyRing(ctx context.Context, clusterAPI certificateSigner, purpose cryptosuites.KeyPurpose) (*client.KeyRing, error) {
signer, err := cryptosuites.GenerateKey(ctx, getCurrentSuiteFromPing(clusterAPI), purpose)
signer, err := cryptosuites.GenerateKey(ctx,
cryptosuites.GetCurrentSuiteFromPing(clusterAPI),
purpose)
if err != nil {
return nil, trace.Wrap(err)
}
Expand Down
Loading