Skip to content

Commit

Permalink
eliminate rsa.GenerateKey and lib/auth/native (#47768)
Browse files Browse the repository at this point in the history
  • Loading branch information
nklaassen authored Oct 21, 2024
1 parent 39e9d82 commit 0a0d413
Show file tree
Hide file tree
Showing 69 changed files with 644 additions and 719 deletions.
4 changes: 2 additions & 2 deletions api/client/proxy/transport/transportv1/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ package transportv1
import (
"bytes"
"context"
"crypto/ed25519"
"crypto/rand"
"crypto/rsa"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -555,7 +555,7 @@ func newServer(t *testing.T, srv transportv1pb.TransportServiceServer) testPack
// newKeyring returns an [agent.ExtendedAgent] that has
// one key populated in it.
func newKeyring(t *testing.T) agent.ExtendedAgent {
private, err := rsa.GenerateKey(rand.Reader, 2048)
_, private, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)

keyring := agent.NewKeyring()
Expand Down
18 changes: 4 additions & 14 deletions api/observability/tracing/ssh/ssh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@ package ssh

import (
"context"
"crypto/ed25519"
"crypto/rand"
"crypto/rsa"
"crypto/subtle"
"crypto/x509"
"encoding/json"
"encoding/pem"
"errors"
"net"
"testing"
Expand Down Expand Up @@ -73,19 +71,11 @@ func (s *server) Stop() error {
}

func generateSigner(t *testing.T) ssh.Signer {
private, err := rsa.GenerateKey(rand.Reader, 2048)
_, private, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)

block := &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(private),
}

privatePEM := pem.EncodeToMemory(block)
signer, err := ssh.ParsePrivateKey(privatePEM)
sshSigner, err := ssh.NewSignerFromSigner(private)
require.NoError(t, err)

return signer
return sshSigner
}

func (s *server) GetClient(t *testing.T) (ssh.Conn, <-chan ssh.NewChannel, <-chan *ssh.Request) {
Expand Down
1 change: 1 addition & 0 deletions api/utils/keys/privatekey_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
)

func TestMarshalAndParseKey(t *testing.T) {
//nolint:forbidigo // Generating a small RSA key allowed for test.
rsaKey, err := rsa.GenerateKey(rand.Reader, 1024)
require.NoError(t, err)
ecKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
Expand Down
2 changes: 2 additions & 0 deletions api/utils/sshutils/checker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ func TestCheckerValidateFIPS(t *testing.T) {
FIPS: true,
}

//nolint:forbidigo // Generating RSA keys allowed for key check test.
rsaKey, err := rsa.GenerateKey(rand.Reader, constants.RSAKeySize)
require.NoError(t, err)
//nolint:forbidigo // Generating RSA keys allowed for key check test.
smallRSAKey, err := rsa.GenerateKey(rand.Reader, 1024)
require.NoError(t, err)
ellipticKeyP224, err := ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
Expand Down
18 changes: 4 additions & 14 deletions api/utils/sshutils/conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ limitations under the License.
package sshutils

import (
"crypto/ed25519"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"net"
"testing"
"time"
Expand Down Expand Up @@ -64,19 +62,11 @@ func (s *server) Stop() error {
}

func generateSigner(t *testing.T) ssh.Signer {
private, err := rsa.GenerateKey(rand.Reader, 2048)
_, private, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err)

block := &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(private),
}

privatePEM := pem.EncodeToMemory(block)
signer, err := ssh.ParsePrivateKey(privatePEM)
sshSigner, err := ssh.NewSignerFromSigner(private)
require.NoError(t, err)

return signer
return sshSigner
}

func (s *server) GetClient(t *testing.T) (ssh.Conn, <-chan ssh.NewChannel, <-chan *ssh.Request) {
Expand Down
51 changes: 29 additions & 22 deletions api/utils/sshutils/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,24 @@ limitations under the License.
package sshutils

import (
"crypto"
"crypto/ed25519"
"crypto/rand"
"crypto/rsa"
"time"

"github.com/gravitational/trace"
"golang.org/x/crypto/ssh"

"github.com/gravitational/teleport/api/constants"
)

const defaultPrincipal = "127.0.0.1"

// MakeTestSSHCA generates a new SSH certificate authority for tests.
func MakeTestSSHCA() (ssh.Signer, error) {
privateKey, err := rsa.GenerateKey(rand.Reader, constants.RSAKeySize)
_, privateKey, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return nil, trace.Wrap(err)
}
ca, err := ssh.NewSignerFromKey(privateKey)
ca, err := ssh.NewSignerFromSigner(privateKey)
if err != nil {
return nil, trace.Wrap(err)
}
Expand All @@ -49,33 +48,41 @@ func MakeSpoofedHostCert(realCA ssh.Signer) (ssh.Signer, error) {
if err != nil {
return nil, trace.Wrap(err)
}
return makeHostCert(realCA.PublicKey(), fakeCA, defaultPrincipal)
_, hostKey, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return nil, trace.Wrap(err)
}
return makeHostCert(hostKey, realCA.PublicKey(), fakeCA, defaultPrincipal)
}

// MakeRealHostCert makes an SSH host certificate that is signed by the
// provided CA.
func MakeRealHostCert(realCA ssh.Signer) (ssh.Signer, error) {
return makeHostCert(realCA.PublicKey(), realCA, defaultPrincipal)
_, hostKey, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return nil, trace.Wrap(err)
}
return makeHostCert(hostKey, realCA.PublicKey(), realCA, defaultPrincipal)
}

// MakeRealHostCertWithKey makes an SSH host certificate with the provided key that is
// signed by the provided CA.
func MakeRealHostCertWithKey(hostKey crypto.Signer, realCA ssh.Signer) (ssh.Signer, error) {
return makeHostCert(hostKey, realCA.PublicKey(), realCA, defaultPrincipal)
}

// MakeRealHostCertWithPrincipals makes an SSH host certificate that is signed by the
// provided CA for the provided principals.
func MakeRealHostCertWithPrincipals(realCA ssh.Signer, principals ...string) (ssh.Signer, error) {
return makeHostCert(realCA.PublicKey(), realCA, principals...)
}

func makeHostCert(signKey ssh.PublicKey, signer ssh.Signer, principals ...string) (ssh.Signer, error) {
priv, err := rsa.GenerateKey(rand.Reader, constants.RSAKeySize)
if err != nil {
return nil, trace.Wrap(err)
}

privSigner, err := ssh.NewSignerFromKey(priv)
_, hostKey, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return nil, trace.Wrap(err)
}
return makeHostCert(hostKey, realCA.PublicKey(), realCA, principals...)
}

pub, err := ssh.NewPublicKey(priv.Public())
func makeHostCert(hostKey crypto.Signer, caPublicKey ssh.PublicKey, caSigner ssh.Signer, principals ...string) (ssh.Signer, error) {
hostSigner, err := ssh.NewSignerFromSigner(hostKey)
if err != nil {
return nil, trace.Wrap(err)
}
Expand All @@ -87,9 +94,9 @@ func makeHostCert(signKey ssh.PublicKey, signer ssh.Signer, principals ...string

cert := &ssh.Certificate{
Nonce: nonce,
Key: pub,
Key: hostSigner.PublicKey(),
CertType: ssh.HostCert,
SignatureKey: signKey,
SignatureKey: caPublicKey,
ValidPrincipals: principals,
ValidBefore: uint64(time.Now().Add(time.Hour).Unix()),
}
Expand All @@ -104,12 +111,12 @@ func makeHostCert(signKey ssh.PublicKey, signer ssh.Signer, principals ...string
bytesForSigning := cert.Marshal()
bytesForSigning = bytesForSigning[:len(bytesForSigning)-4]

cert.Signature, err = signer.Sign(rand.Reader, bytesForSigning)
cert.Signature, err = caSigner.Sign(rand.Reader, bytesForSigning)
if err != nil {
return nil, trace.Wrap(err)
}

certSigner, err := ssh.NewCertSigner(cert, privSigner)
certSigner, err := ssh.NewCertSigner(cert, hostSigner)
if err != nil {
return nil, trace.Wrap(err)
}
Expand Down
18 changes: 11 additions & 7 deletions integration/helpers/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ package helpers
import (
"bytes"
"context"
"crypto/rsa"
"crypto/tls"
"crypto/x509/pkix"
"encoding/json"
Expand All @@ -47,6 +46,7 @@ import (
"github.com/gravitational/teleport/api/breaker"
clientproto "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/auth/keygen"
"github.com/gravitational/teleport/lib/auth/state"
Expand All @@ -55,6 +55,7 @@ import (
"github.com/gravitational/teleport/lib/backend/lite"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/cloud/imds"
"github.com/gravitational/teleport/lib/cryptosuites"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/events"
"github.com/gravitational/teleport/lib/httplib/csrf"
Expand Down Expand Up @@ -343,24 +344,27 @@ func NewInstance(t *testing.T, cfg InstanceConfig) *TeleInstance {
}

// generate instance secrets (keys):
keygen := keygen.New(context.TODO())
if cfg.Priv == nil || cfg.Pub == nil {
cfg.Priv, cfg.Pub, _ = keygen.GenerateKeyPair()
privateKey, err := cryptosuites.GeneratePrivateKeyWithAlgorithm(cryptosuites.ECDSAP256)
fatalIf(err)
cfg.Priv = privateKey.PrivateKeyPEM()
cfg.Pub = privateKey.MarshalSSHPublicKey()
}
rsaKey, err := ssh.ParseRawPrivateKey(cfg.Priv)
key, err := keys.ParsePrivateKey(cfg.Priv)
fatalIf(err)

tlsCACert, err := tlsca.GenerateSelfSignedCAWithSigner(rsaKey.(*rsa.PrivateKey), pkix.Name{
tlsCACert, err := tlsca.GenerateSelfSignedCAWithSigner(key, pkix.Name{
CommonName: cfg.ClusterName,
Organization: []string{cfg.ClusterName},
}, nil, defaults.CATTL)
fatalIf(err)

signer, err := ssh.ParsePrivateKey(cfg.Priv)
sshSigner, err := ssh.NewSignerFromSigner(key)
fatalIf(err)

keygen := keygen.New(context.TODO())
cert, err := keygen.GenerateHostCert(services.HostCertParams{
CASigner: signer,
CASigner: sshSigner,
PublicHostKey: cfg.Pub,
HostID: cfg.HostID,
NodeName: cfg.NodeName,
Expand Down
4 changes: 2 additions & 2 deletions integration/helpers/testmain.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"testing"
"time"

"github.com/gravitational/teleport/lib/auth/native"
"github.com/gravitational/teleport/lib/cryptosuites"
"github.com/gravitational/teleport/lib/modules"
"github.com/gravitational/teleport/lib/srv"
"github.com/gravitational/teleport/lib/utils"
Expand All @@ -34,7 +34,7 @@ import (
// it as an argument. Otherwise, it will run tests as normal.
func TestMainImplementation(m *testing.M) {
utils.InitLoggerForTests()
native.PrecomputeTestKeys(m)
cryptosuites.PrecomputeRSATestKeys(m)
SetTestTimeouts(3 * time.Second)
modules.SetInsecureTestMode(true)
// If the test is re-executing itself, execute the command that comes over
Expand Down
6 changes: 3 additions & 3 deletions integration/kube/fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/utils/keys"
"github.com/gravitational/teleport/integration/helpers"
"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"
"github.com/gravitational/teleport/lib/utils"
Expand Down Expand Up @@ -88,11 +88,11 @@ func ProxyClient(cfg ProxyConfig) (*kubernetes.Clientset, *rest.Config, error) {
if err != nil {
return nil, nil, trace.Wrap(err)
}
privPEM, _, err := native.GenerateKeyPair()
priv, err := cryptosuites.GenerateKeyWithAlgorithm(cryptosuites.ECDSAP256)
if err != nil {
return nil, nil, trace.Wrap(err)
}
priv, err := keys.ParsePrivateKey(privPEM)
privPEM, err := keys.MarshalPrivateKey(priv)
if err != nil {
return nil, nil, trace.Wrap(err)
}
Expand Down
1 change: 1 addition & 0 deletions integrations/event-handler/mtls_certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ func (c *MTLSCerts) generate(length int) error {
// genCertAndPK generates and returns certificate and primary key
func (c *MTLSCerts) genCertAndPK(length int, cert *x509.Certificate, parent *x509.Certificate, signer *rsa.PrivateKey) (*rsa.PrivateKey, []byte, error) {
// Generate PK
//nolint:forbidigo // Allow integration to generate RSA key without importing Teleport.
pk, err := rsa.GenerateKey(rand.Reader, length)
if err != nil {
return nil, nil, trace.Wrap(err)
Expand Down
10 changes: 5 additions & 5 deletions integrations/lib/credentials/credentials_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ package credentials

import (
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
Expand All @@ -33,6 +32,7 @@ import (
"golang.org/x/crypto/ssh"

"github.com/gravitational/teleport/api/client"
"github.com/gravitational/teleport/lib/cryptosuites"
)

// mockTLSCredentials mocks insecure Client credentials.
Expand Down Expand Up @@ -85,13 +85,13 @@ func TestCheckExpiredCredentials(t *testing.T) {
NotAfter: time.Now().Add(1 * time.Hour),
}

caKey, err := rsa.GenerateKey(rand.Reader, 1024)
caKey, err := cryptosuites.GenerateKeyWithAlgorithm(cryptosuites.ECDSAP256)
require.NoError(t, err)
clientKey, err := rsa.GenerateKey(rand.Reader, 1024)
clientKey, err := cryptosuites.GenerateKeyWithAlgorithm(cryptosuites.ECDSAP256)
require.NoError(t, err)
validCertBytes, err := x509.CreateCertificate(rand.Reader, validCert, ca, &clientKey.PublicKey, caKey)
validCertBytes, err := x509.CreateCertificate(rand.Reader, validCert, ca, clientKey.Public(), caKey)
require.NoError(t, err)
invalidCertBytes, err := x509.CreateCertificate(rand.Reader, expiredCert, ca, &clientKey.PublicKey, caKey)
invalidCertBytes, err := x509.CreateCertificate(rand.Reader, expiredCert, ca, clientKey.Public(), caKey)
require.NoError(t, err)

expiredCred := &mockTLSCredentials{CertificateChain: &tls.Certificate{Certificate: [][]byte{invalidCertBytes}}}
Expand Down
Loading

0 comments on commit 0a0d413

Please sign in to comment.