Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
nklaassen committed Sep 19, 2024
1 parent 9a0f8d6 commit 254361f
Show file tree
Hide file tree
Showing 9 changed files with 324 additions and 14 deletions.
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

0 comments on commit 254361f

Please sign in to comment.