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

wip #46743

Closed
wants to merge 1 commit into from
Closed

wip #46743

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
72 changes: 71 additions & 1 deletion api/types/authentication.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,13 @@ type AuthPreference interface {
GetSignatureAlgorithmSuite() SignatureAlgorithmSuite
// SetSignatureAlgorithmSuite sets the signature algorithm suite.
SetSignatureAlgorithmSuite(SignatureAlgorithmSuite)
// SetDefaultSignatureAlgorithmSuite sets default signature algorithm suite
// based on the params. This is meant for a default auth preference in a
// brand new cluster or after resetting the auth preference.
SetDefaultSignatureAlgorithmSuite(SignatureAlgorithmSuiteParams)
// CheckSignatureAlgorithmSuite returns an error if the current signature
// algorithm suite is incompatible with [params].
CheckSignatureAlgorithmSuite(SignatureAlgorithmSuiteParams) error

// String represents a human readable version of authentication settings.
String() string
Expand Down Expand Up @@ -216,7 +223,15 @@ func newAuthPreferenceWithLabels(spec AuthPreferenceSpecV2, labels map[string]st

// DefaultAuthPreference returns the default authentication preferences.
func DefaultAuthPreference() AuthPreference {
authPref, _ := newAuthPreferenceWithLabels(AuthPreferenceSpecV2{}, map[string]string{
authPref, _ := newAuthPreferenceWithLabels(AuthPreferenceSpecV2{
// This is useful as a static value, but the real default signature
// algorithm suite depends on the cluster FIPS and HSM settings, and
// gets written by [AuthPreferenceV2.SetDefaultSignatureAlgorithmSuite]
// wherever a default auth preference will actually be persisted.
// It is set here so that many existing tests using this get the
// benefits of the balanced-v1 suite.
SignatureAlgorithmSuite: SignatureAlgorithmSuite_SIGNATURE_ALGORITHM_SUITE_BALANCED_V1,
}, map[string]string{
OriginLabel: OriginDefaults,
})
return authPref
Expand Down Expand Up @@ -567,6 +582,61 @@ func (c *AuthPreferenceV2) SetSignatureAlgorithmSuite(suite SignatureAlgorithmSu
c.Spec.SignatureAlgorithmSuite = suite
}

// SignatureAlgorithmSuiteParams is a set of parameters used to determine if a
// configured signature algorithm suite is valid, or to set a default signature
// algorithm suite.
type SignatureAlgorithmSuiteParams struct {
// FIPS should be true if running in FIPS mode.
FIPS bool
// UsingHSMOrKMS should be true if the auth server is configured to
// use an HSM or KMS.
UsingHSMOrKMS bool
}

// SetDefaultSignatureAlgorithmSuite sets default signature algorithm suite
// based on the params. This is meant for a default auth preference in a
// brand new cluster or after resetting the auth preference.
func (c *AuthPreferenceV2) SetDefaultSignatureAlgorithmSuite(params SignatureAlgorithmSuiteParams) {
switch {
case params.FIPS:
c.SetSignatureAlgorithmSuite(SignatureAlgorithmSuite_SIGNATURE_ALGORITHM_SUITE_FIPS_V1)
case params.UsingHSMOrKMS:
c.SetSignatureAlgorithmSuite(SignatureAlgorithmSuite_SIGNATURE_ALGORITHM_SUITE_HSM_V1)
default:
c.SetSignatureAlgorithmSuite(SignatureAlgorithmSuite_SIGNATURE_ALGORITHM_SUITE_BALANCED_V1)
}
}

var (
errNonFIPSSignatureAlgorithmSuite = &trace.BadParameterError{Message: `non-FIPS compliant authentication setting: "signature_algorithm_suite" must be "fips-v1" or "legacy"`}
errNonHSMSignatureAlgorithmSuite = &trace.BadParameterError{Message: fmt.Sprintf(`configured "signature_algorithm_suite" is unsupported when "ca_key_params" configures an HSM or KMS, supported values: %v`, []string{"hsm-v1", "fips-v1", "legacy"})}
)

// CheckSignatureAlgorithmSuite returns an error if the current signature
// algorithm suite is incompatible with [params].
func (c *AuthPreferenceV2) CheckSignatureAlgorithmSuite(params SignatureAlgorithmSuiteParams) error {
switch c.GetSignatureAlgorithmSuite() {
case SignatureAlgorithmSuite_SIGNATURE_ALGORITHM_SUITE_UNSPECIFIED,
SignatureAlgorithmSuite_SIGNATURE_ALGORITHM_SUITE_LEGACY,
SignatureAlgorithmSuite_SIGNATURE_ALGORITHM_SUITE_FIPS_V1:
// legacy, fips-v1, and unspecified are always valid.
case SignatureAlgorithmSuite_SIGNATURE_ALGORITHM_SUITE_HSM_V1:
if params.FIPS {
return errNonFIPSSignatureAlgorithmSuite
}
case SignatureAlgorithmSuite_SIGNATURE_ALGORITHM_SUITE_BALANCED_V1:
if params.FIPS {
return trace.Wrap(errNonFIPSSignatureAlgorithmSuite)
}
if params.UsingHSMOrKMS {
return trace.Wrap(errNonHSMSignatureAlgorithmSuite)
}
default:
return trace.Errorf("unhandled signature_algorithm_suite: this is a bug")
}
return nil
}

// CheckAndSetDefaults verifies the constraints for AuthPreference.
func (c *AuthPreferenceV2) CheckAndSetDefaults() error {
c.setStaticFields()
Expand Down
11 changes: 11 additions & 0 deletions lib/auth/auth_with_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -4699,6 +4699,13 @@ func (a *ServerWithRoles) SetAuthPreference(ctx context.Context, newAuthPref typ
}
}

if err := newAuthPref.CheckSignatureAlgorithmSuite(types.SignatureAlgorithmSuiteParams{
FIPS: a.authServer.fips,
UsingHSMOrKMS: a.authServer.keyStore.UsingHSMOrKMS(),
}); err != nil {
return trace.Wrap(err)
}

if err := dtconfig.ValidateConfigAgainstModules(newAuthPref.GetDeviceTrust()); err != nil {
return trace.Wrap(err)
}
Expand Down Expand Up @@ -4752,6 +4759,10 @@ func (a *ServerWithRoles) ResetAuthPreference(ctx context.Context) error {
}

defaultAuthPref := types.DefaultAuthPreference()
defaultAuthPref.SetDefaultSignatureAlgorithmSuite(types.SignatureAlgorithmSuiteParams{
FIPS: a.authServer.fips,
UsingHSMOrKMS: a.authServer.keyStore.UsingHSMOrKMS(),
})
_, err = a.authServer.UpsertAuthPreference(ctx, defaultAuthPref)

var msg string
Expand Down
41 changes: 28 additions & 13 deletions lib/auth/clusterconfig/clusterconfigv1/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,13 @@ type Backend interface {

// ServiceConfig contain dependencies required to create a [Service].
type ServiceConfig struct {
Cache Cache
Backend Backend
Authorizer authz.Authorizer
Emitter apievents.Emitter
AccessGraph AccessGraphConfig
ReadOnlyCache ReadOnlyCache
Cache Cache
Backend Backend
Authorizer authz.Authorizer
Emitter apievents.Emitter
AccessGraph AccessGraphConfig
ReadOnlyCache ReadOnlyCache
SignatureAlgorithmSuiteParams types.SignatureAlgorithmSuiteParams
}

// AccessGraphConfig contains the configuration about the access graph service
Expand All @@ -99,12 +100,13 @@ type AccessGraphConfig struct {
type Service struct {
clusterconfigpb.UnimplementedClusterConfigServiceServer

cache Cache
backend Backend
authorizer authz.Authorizer
emitter apievents.Emitter
accessGraph AccessGraphConfig
readOnlyCache ReadOnlyCache
cache Cache
backend Backend
authorizer authz.Authorizer
emitter apievents.Emitter
accessGraph AccessGraphConfig
readOnlyCache ReadOnlyCache
signatureAlgorithmSuiteParams types.SignatureAlgorithmSuiteParams
}

// NewService validates the provided configuration and returns a [Service].
Expand All @@ -130,7 +132,7 @@ func NewService(cfg ServiceConfig) (*Service, error) {
cfg.ReadOnlyCache = readOnlyCache
}

return &Service{cache: cfg.Cache, backend: cfg.Backend, authorizer: cfg.Authorizer, emitter: cfg.Emitter, accessGraph: cfg.AccessGraph, readOnlyCache: cfg.ReadOnlyCache}, nil
return &Service{cache: cfg.Cache, backend: cfg.Backend, authorizer: cfg.Authorizer, emitter: cfg.Emitter, accessGraph: cfg.AccessGraph, readOnlyCache: cfg.ReadOnlyCache, signatureAlgorithmSuiteParams: cfg.SignatureAlgorithmSuiteParams}, nil
}

// GetAuthPreference returns the locally cached auth preference.
Expand Down Expand Up @@ -179,6 +181,10 @@ func (s *Service) CreateAuthPreference(ctx context.Context, p types.AuthPreferen
return nil, trace.Wrap(err)
}

if err := p.CheckSignatureAlgorithmSuite(s.signatureAlgorithmSuiteParams); err != nil {
return nil, trace.Wrap(err)
}

created, err := s.backend.CreateAuthPreference(ctx, p)
if err != nil {
return nil, trace.Wrap(err)
Expand Down Expand Up @@ -230,6 +236,10 @@ func (s *Service) UpdateAuthPreference(ctx context.Context, req *clusterconfigpb
return nil, trace.Wrap(err)
}

if err := req.AuthPreference.CheckSignatureAlgorithmSuite(s.signatureAlgorithmSuiteParams); err != nil {
return nil, trace.Wrap(err)
}

req.AuthPreference.SetOrigin(types.OriginDynamic)

original, err := s.cache.GetAuthPreference(ctx)
Expand Down Expand Up @@ -293,6 +303,10 @@ func (s *Service) UpsertAuthPreference(ctx context.Context, req *clusterconfigpb
return nil, trace.Wrap(err)
}

if err := req.AuthPreference.CheckSignatureAlgorithmSuite(s.signatureAlgorithmSuiteParams); err != nil {
return nil, trace.Wrap(err)
}

req.AuthPreference.SetOrigin(types.OriginDynamic)

original, err := s.cache.GetAuthPreference(ctx)
Expand Down Expand Up @@ -347,6 +361,7 @@ func (s *Service) ResetAuthPreference(ctx context.Context, _ *clusterconfigpb.Re
}

defaultPreference := types.DefaultAuthPreference()
defaultPreference.SetDefaultSignatureAlgorithmSuite(s.signatureAlgorithmSuiteParams)
newSecondFactor := defaultPreference.GetSecondFactor()
const iterationLimit = 3
// Attempt a few iterations in case the conditional update fails
Expand Down
4 changes: 4 additions & 0 deletions lib/auth/grpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -5367,6 +5367,10 @@ func NewGRPCServer(cfg GRPCServerConfig) (*GRPCServer, error) {
Insecure: cfg.APIConfig.AccessGraph.Insecure,
},
ReadOnlyCache: cfg.AuthServer.ReadOnlyCache,
SignatureAlgorithmSuiteParams: types.SignatureAlgorithmSuiteParams{
FIPS: cfg.AuthServer.fips,
UsingHSMOrKMS: cfg.AuthServer.keyStore.UsingHSMOrKMS(),
},
})
if err != nil {
return nil, trace.Wrap(err)
Expand Down
7 changes: 7 additions & 0 deletions lib/auth/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import (
"github.com/gravitational/teleport/lib/events"
"github.com/gravitational/teleport/lib/events/eventstest"
"github.com/gravitational/teleport/lib/limiter"
"github.com/gravitational/teleport/lib/service/servicecfg"
"github.com/gravitational/teleport/lib/services"
"github.com/gravitational/teleport/lib/services/local"
"github.com/gravitational/teleport/lib/services/suite"
Expand Down Expand Up @@ -93,6 +94,10 @@ type TestAuthServerConfig struct {
// RunWhileLockedRetryInterval is the interval to retry the run while locked
// operation.
RunWhileLockedRetryInterval time.Duration
// FIPS means the cluster should run in FIPS mode.
FIPS bool
// KeystoreConfig is configuration for the CA keystore.
KeystoreConfig servicecfg.KeystoreConfig
}

// CheckAndSetDefaults checks and sets defaults
Expand Down Expand Up @@ -298,6 +303,8 @@ func NewTestAuthServer(cfg TestAuthServerConfig) (*TestAuthServer, error) {
ClusterName: clusterName,
HostUUID: uuid.New().String(),
AccessLists: accessLists,
FIPS: cfg.FIPS,
KeyStoreConfig: cfg.KeystoreConfig,
},
WithClock(cfg.Clock),
)
Expand Down
15 changes: 15 additions & 0 deletions lib/auth/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,13 @@ func initializeAuthPreference(ctx context.Context, asrv *Server, newAuthPref typ

if storedAuthPref == nil {
log.Infof("Creating cluster auth preference: %v.", newAuthPref)

// Set a default signature algorithm suite for a new cluster.
newAuthPref.SetDefaultSignatureAlgorithmSuite(types.SignatureAlgorithmSuiteParams{
FIPS: asrv.fips,
UsingHSMOrKMS: asrv.keyStore.UsingHSMOrKMS(),
})

_, err := asrv.CreateAuthPreference(ctx, newAuthPref)
if trace.IsAlreadyExists(err) {
continue
Expand All @@ -785,6 +792,14 @@ func initializeAuthPreference(ctx context.Context, asrv *Server, newAuthPref typ
return trace.Wrap(err)
}

if newAuthPref.Origin() == types.OriginDefaults {
// Never overwrite a stored signature algorithm suite with a default
// signature algorithm suite. This prevents the suite from being
// "upgraded" by a Teleport version upgrade alone, even if defaults
// are used on both versions.
newAuthPref.SetSignatureAlgorithmSuite(storedAuthPref.GetSignatureAlgorithmSuite())
}

newAuthPref.SetRevision(storedAuthPref.GetRevision())
_, err = asrv.UpdateAuthPreference(ctx, newAuthPref)
if trace.IsCompareFailed(err) {
Expand Down
Loading
Loading