Skip to content

Commit

Permalink
eliminate GenerateRSAKeyRing
Browse files Browse the repository at this point in the history
  • Loading branch information
nklaassen committed Oct 5, 2024
1 parent a6c3742 commit b2b46d8
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 32 deletions.
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

0 comments on commit b2b46d8

Please sign in to comment.