Refactor instantiation of policy engines

Instead of using the `base` struct, the x509 and SSH policy
engines are now added to each provisioner directly.
This commit is contained in:
Herman Slatman 2022-01-25 16:45:25 +01:00
parent 066bf32086
commit 512b8d6730
No known key found for this signature in database
GPG key ID: F4D8A44EA0A75A4F
14 changed files with 100 additions and 95 deletions

View file

@ -8,19 +8,21 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/smallstep/certificates/errs" "github.com/smallstep/certificates/errs"
"github.com/smallstep/certificates/policy"
) )
// ACME is the acme provisioner type, an entity that can authorize the ACME // ACME is the acme provisioner type, an entity that can authorize the ACME
// provisioning flow. // provisioning flow.
type ACME struct { type ACME struct {
*base *base
ID string `json:"-"` ID string `json:"-"`
Type string `json:"type"` Type string `json:"type"`
Name string `json:"name"` Name string `json:"name"`
ForceCN bool `json:"forceCN,omitempty"` ForceCN bool `json:"forceCN,omitempty"`
Claims *Claims `json:"claims,omitempty"` Claims *Claims `json:"claims,omitempty"`
Options *Options `json:"options,omitempty"` Options *Options `json:"options,omitempty"`
claimer *Claimer claimer *Claimer
x509Policy policy.X509NamePolicyEngine
} }
// GetID returns the provisioner unique identifier. // GetID returns the provisioner unique identifier.
@ -70,7 +72,6 @@ func (p *ACME) DefaultTLSCertDuration() time.Duration {
// Init initializes and validates the fields of an ACME type. // Init initializes and validates the fields of an ACME type.
func (p *ACME) Init(config Config) (err error) { func (p *ACME) Init(config Config) (err error) {
p.base = &base{} // prevent nil pointers
switch { switch {
case p.Type == "": case p.Type == "":
return errors.New("provisioner type cannot be empty") return errors.New("provisioner type cannot be empty")
@ -86,7 +87,7 @@ func (p *ACME) Init(config Config) (err error) {
// Initialize the x509 allow/deny policy engine // Initialize the x509 allow/deny policy engine
// TODO(hs): ensure no race conditions happen when reloading settings and requesting certs? // TODO(hs): ensure no race conditions happen when reloading settings and requesting certs?
// TODO(hs): implement memoization strategy, so that reloading is not required when no changes were made to allow/deny? // TODO(hs): implement memoization strategy, so that reloading is not required when no changes were made to allow/deny?
if p.x509PolicyEngine, err = newX509PolicyEngine(p.Options.GetX509Options()); err != nil { if p.x509Policy, err = newX509PolicyEngine(p.Options.GetX509Options()); err != nil {
return err return err
} }
@ -113,16 +114,16 @@ type ACMEIdentifier struct {
// certificate for the Identifiers provided in an Order. // certificate for the Identifiers provided in an Order.
func (p *ACME) AuthorizeOrderIdentifier(ctx context.Context, identifier string) error { func (p *ACME) AuthorizeOrderIdentifier(ctx context.Context, identifier string) error {
if p.x509PolicyEngine == nil { if p.x509Policy == nil {
return nil return nil
} }
// assuming only valid identifiers (IP or DNS) are provided // assuming only valid identifiers (IP or DNS) are provided
var err error var err error
if ip := net.ParseIP(identifier); ip != nil { if ip := net.ParseIP(identifier); ip != nil {
_, err = p.x509PolicyEngine.IsIPAllowed(ip) _, err = p.x509Policy.IsIPAllowed(ip)
} else { } else {
_, err = p.x509PolicyEngine.IsDNSAllowed(identifier) _, err = p.x509Policy.IsDNSAllowed(identifier)
} }
return err return err
@ -140,7 +141,7 @@ func (p *ACME) AuthorizeSign(ctx context.Context, token string) ([]SignOption, e
// validators // validators
defaultPublicKeyValidator{}, defaultPublicKeyValidator{},
newValidityValidator(p.claimer.MinTLSCertDuration(), p.claimer.MaxTLSCertDuration()), newValidityValidator(p.claimer.MinTLSCertDuration(), p.claimer.MaxTLSCertDuration()),
newX509NamePolicyValidator(p.x509PolicyEngine), newX509NamePolicyValidator(p.x509Policy),
} }
return opts, nil return opts, nil

View file

@ -18,6 +18,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/smallstep/certificates/errs" "github.com/smallstep/certificates/errs"
"github.com/smallstep/certificates/policy"
"go.step.sm/crypto/jose" "go.step.sm/crypto/jose"
"go.step.sm/crypto/sshutil" "go.step.sm/crypto/sshutil"
"go.step.sm/crypto/x509util" "go.step.sm/crypto/x509util"
@ -267,6 +268,8 @@ type AWS struct {
claimer *Claimer claimer *Claimer
config *awsConfig config *awsConfig
audiences Audiences audiences Audiences
x509Policy policy.X509NamePolicyEngine
sshPolicy policy.SSHNamePolicyEngine
} }
// GetID returns the provisioner unique identifier. // GetID returns the provisioner unique identifier.
@ -392,7 +395,6 @@ func (p *AWS) GetIdentityToken(subject, caURL string) (string, error) {
// Init validates and initializes the AWS provisioner. // Init validates and initializes the AWS provisioner.
func (p *AWS) Init(config Config) (err error) { func (p *AWS) Init(config Config) (err error) {
p.base = &base{} // prevent nil pointers
switch { switch {
case p.Type == "": case p.Type == "":
return errors.New("provisioner type cannot be empty") return errors.New("provisioner type cannot be empty")
@ -427,12 +429,12 @@ func (p *AWS) Init(config Config) (err error) {
} }
// Initialize the x509 allow/deny policy engine // Initialize the x509 allow/deny policy engine
if p.x509PolicyEngine, err = newX509PolicyEngine(p.Options.GetX509Options()); err != nil { if p.x509Policy, err = newX509PolicyEngine(p.Options.GetX509Options()); err != nil {
return err return err
} }
// Initialize the SSH allow/deny policy engine // Initialize the SSH allow/deny policy engine
if p.sshPolicyEngine, err = newSSHPolicyEngine(p.Options.GetSSHOptions()); err != nil { if p.sshPolicy, err = newSSHPolicyEngine(p.Options.GetSSHOptions()); err != nil {
return err return err
} }
@ -489,7 +491,7 @@ func (p *AWS) AuthorizeSign(ctx context.Context, token string) ([]SignOption, er
defaultPublicKeyValidator{}, defaultPublicKeyValidator{},
commonNameValidator(payload.Claims.Subject), commonNameValidator(payload.Claims.Subject),
newValidityValidator(p.claimer.MinTLSCertDuration(), p.claimer.MaxTLSCertDuration()), newValidityValidator(p.claimer.MinTLSCertDuration(), p.claimer.MaxTLSCertDuration()),
newX509NamePolicyValidator(p.x509PolicyEngine), newX509NamePolicyValidator(p.x509Policy),
), nil ), nil
} }
@ -772,6 +774,6 @@ func (p *AWS) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption,
// Require all the fields in the SSH certificate // Require all the fields in the SSH certificate
&sshCertDefaultValidator{}, &sshCertDefaultValidator{},
// Ensure that all principal names are allowed // Ensure that all principal names are allowed
newSSHNamePolicyValidator(p.sshPolicyEngine), newSSHNamePolicyValidator(p.sshPolicy),
), nil ), nil
} }

View file

@ -14,6 +14,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/smallstep/certificates/errs" "github.com/smallstep/certificates/errs"
"github.com/smallstep/certificates/policy"
"go.step.sm/crypto/jose" "go.step.sm/crypto/jose"
"go.step.sm/crypto/sshutil" "go.step.sm/crypto/sshutil"
"go.step.sm/crypto/x509util" "go.step.sm/crypto/x509util"
@ -98,6 +99,8 @@ type Azure struct {
config *azureConfig config *azureConfig
oidcConfig openIDConfiguration oidcConfig openIDConfiguration
keyStore *keyStore keyStore *keyStore
x509Policy policy.X509NamePolicyEngine
sshPolicy policy.SSHNamePolicyEngine
} }
// GetID returns the provisioner unique identifier. // GetID returns the provisioner unique identifier.
@ -191,7 +194,6 @@ func (p *Azure) GetIdentityToken(subject, caURL string) (string, error) {
// Init validates and initializes the Azure provisioner. // Init validates and initializes the Azure provisioner.
func (p *Azure) Init(config Config) (err error) { func (p *Azure) Init(config Config) (err error) {
p.base = &base{} // prevent nil pointers
switch { switch {
case p.Type == "": case p.Type == "":
return errors.New("provisioner type cannot be empty") return errors.New("provisioner type cannot be empty")
@ -223,12 +225,12 @@ func (p *Azure) Init(config Config) (err error) {
} }
// Initialize the x509 allow/deny policy engine // Initialize the x509 allow/deny policy engine
if p.x509PolicyEngine, err = newX509PolicyEngine(p.Options.GetX509Options()); err != nil { if p.x509Policy, err = newX509PolicyEngine(p.Options.GetX509Options()); err != nil {
return err return err
} }
// Initialize the SSH allow/deny policy engine // Initialize the SSH allow/deny policy engine
if p.sshPolicyEngine, err = newSSHPolicyEngine(p.Options.GetSSHOptions()); err != nil { if p.sshPolicy, err = newSSHPolicyEngine(p.Options.GetSSHOptions()); err != nil {
return err return err
} }
@ -339,7 +341,7 @@ func (p *Azure) AuthorizeSign(ctx context.Context, token string) ([]SignOption,
// validators // validators
defaultPublicKeyValidator{}, defaultPublicKeyValidator{},
newValidityValidator(p.claimer.MinTLSCertDuration(), p.claimer.MaxTLSCertDuration()), newValidityValidator(p.claimer.MinTLSCertDuration(), p.claimer.MaxTLSCertDuration()),
newX509NamePolicyValidator(p.x509PolicyEngine), newX509NamePolicyValidator(p.x509Policy),
), nil ), nil
} }
@ -409,7 +411,7 @@ func (p *Azure) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOptio
// Require all the fields in the SSH certificate // Require all the fields in the SSH certificate
&sshCertDefaultValidator{}, &sshCertDefaultValidator{},
// Ensure that all principal names are allowed // Ensure that all principal names are allowed
newSSHNamePolicyValidator(p.sshPolicyEngine), newSSHNamePolicyValidator(p.sshPolicy),
), nil ), nil
} }

View file

@ -15,6 +15,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/smallstep/certificates/errs" "github.com/smallstep/certificates/errs"
"github.com/smallstep/certificates/policy"
"go.step.sm/crypto/jose" "go.step.sm/crypto/jose"
"go.step.sm/crypto/sshutil" "go.step.sm/crypto/sshutil"
"go.step.sm/crypto/x509util" "go.step.sm/crypto/x509util"
@ -92,6 +93,8 @@ type GCP struct {
config *gcpConfig config *gcpConfig
keyStore *keyStore keyStore *keyStore
audiences Audiences audiences Audiences
x509Policy policy.X509NamePolicyEngine
sshPolicy policy.SSHNamePolicyEngine
} }
// GetID returns the provisioner unique identifier. The name should uniquely // GetID returns the provisioner unique identifier. The name should uniquely
@ -195,7 +198,6 @@ func (p *GCP) GetIdentityToken(subject, caURL string) (string, error) {
// Init validates and initializes the GCP provisioner. // Init validates and initializes the GCP provisioner.
func (p *GCP) Init(config Config) error { func (p *GCP) Init(config Config) error {
p.base = &base{} // prevent nil pointers
var err error var err error
switch { switch {
case p.Type == "": case p.Type == "":
@ -218,12 +220,12 @@ func (p *GCP) Init(config Config) error {
} }
// Initialize the x509 allow/deny policy engine // Initialize the x509 allow/deny policy engine
if p.x509PolicyEngine, err = newX509PolicyEngine(p.Options.GetX509Options()); err != nil { if p.x509Policy, err = newX509PolicyEngine(p.Options.GetX509Options()); err != nil {
return err return err
} }
// Initialize the SSH allow/deny policy engine // Initialize the SSH allow/deny policy engine
if p.sshPolicyEngine, err = newSSHPolicyEngine(p.Options.GetSSHOptions()); err != nil { if p.sshPolicy, err = newSSHPolicyEngine(p.Options.GetSSHOptions()); err != nil {
return err return err
} }
@ -284,7 +286,7 @@ func (p *GCP) AuthorizeSign(ctx context.Context, token string) ([]SignOption, er
// validators // validators
defaultPublicKeyValidator{}, defaultPublicKeyValidator{},
newValidityValidator(p.claimer.MinTLSCertDuration(), p.claimer.MaxTLSCertDuration()), newValidityValidator(p.claimer.MinTLSCertDuration(), p.claimer.MaxTLSCertDuration()),
newX509NamePolicyValidator(p.x509PolicyEngine), newX509NamePolicyValidator(p.x509Policy),
), nil ), nil
} }
@ -451,6 +453,6 @@ func (p *GCP) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption,
// Require all the fields in the SSH certificate // Require all the fields in the SSH certificate
&sshCertDefaultValidator{}, &sshCertDefaultValidator{},
// Ensure that all principal names are allowed // Ensure that all principal names are allowed
newSSHNamePolicyValidator(p.sshPolicyEngine), newSSHNamePolicyValidator(p.sshPolicy),
), nil ), nil
} }

View file

@ -8,6 +8,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/smallstep/certificates/errs" "github.com/smallstep/certificates/errs"
"github.com/smallstep/certificates/policy"
"go.step.sm/crypto/jose" "go.step.sm/crypto/jose"
"go.step.sm/crypto/sshutil" "go.step.sm/crypto/sshutil"
"go.step.sm/crypto/x509util" "go.step.sm/crypto/x509util"
@ -37,6 +38,8 @@ type JWK struct {
Options *Options `json:"options,omitempty"` Options *Options `json:"options,omitempty"`
claimer *Claimer claimer *Claimer
audiences Audiences audiences Audiences
x509Policy policy.X509NamePolicyEngine
sshPolicy policy.SSHNamePolicyEngine
} }
// GetID returns the provisioner unique identifier. The name and credential id // GetID returns the provisioner unique identifier. The name and credential id
@ -89,7 +92,6 @@ func (p *JWK) GetEncryptedKey() (string, string, bool) {
// Init initializes and validates the fields of a JWK type. // Init initializes and validates the fields of a JWK type.
func (p *JWK) Init(config Config) (err error) { func (p *JWK) Init(config Config) (err error) {
p.base = &base{} // prevent nil pointers
switch { switch {
case p.Type == "": case p.Type == "":
return errors.New("provisioner type cannot be empty") return errors.New("provisioner type cannot be empty")
@ -105,12 +107,12 @@ func (p *JWK) Init(config Config) (err error) {
} }
// Initialize the x509 allow/deny policy engine // Initialize the x509 allow/deny policy engine
if p.x509PolicyEngine, err = newX509PolicyEngine(p.Options.GetX509Options()); err != nil { if p.x509Policy, err = newX509PolicyEngine(p.Options.GetX509Options()); err != nil {
return err return err
} }
// Initialize the SSH allow/deny policy engine // Initialize the SSH allow/deny policy engine
if p.sshPolicyEngine, err = newSSHPolicyEngine(p.Options.GetSSHOptions()); err != nil { if p.sshPolicy, err = newSSHPolicyEngine(p.Options.GetSSHOptions()); err != nil {
return err return err
} }
@ -197,7 +199,7 @@ func (p *JWK) AuthorizeSign(ctx context.Context, token string) ([]SignOption, er
defaultPublicKeyValidator{}, defaultPublicKeyValidator{},
defaultSANsValidator(claims.SANs), defaultSANsValidator(claims.SANs),
newValidityValidator(p.claimer.MinTLSCertDuration(), p.claimer.MaxTLSCertDuration()), newValidityValidator(p.claimer.MinTLSCertDuration(), p.claimer.MaxTLSCertDuration()),
newX509NamePolicyValidator(p.x509PolicyEngine), newX509NamePolicyValidator(p.x509Policy),
}, nil }, nil
} }
@ -292,7 +294,7 @@ func (p *JWK) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption,
// Require and validate all the default fields in the SSH certificate. // Require and validate all the default fields in the SSH certificate.
&sshCertDefaultValidator{}, &sshCertDefaultValidator{},
// Ensure that all principal names are allowed // Ensure that all principal names are allowed
newSSHNamePolicyValidator(p.sshPolicyEngine), newSSHNamePolicyValidator(p.sshPolicy),
), nil ), nil
} }

View file

@ -11,6 +11,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/smallstep/certificates/errs" "github.com/smallstep/certificates/errs"
"github.com/smallstep/certificates/policy"
"go.step.sm/crypto/jose" "go.step.sm/crypto/jose"
"go.step.sm/crypto/pemutil" "go.step.sm/crypto/pemutil"
"go.step.sm/crypto/sshutil" "go.step.sm/crypto/sshutil"
@ -51,7 +52,9 @@ type K8sSA struct {
claimer *Claimer claimer *Claimer
audiences Audiences audiences Audiences
//kauthn kauthn.AuthenticationV1Interface //kauthn kauthn.AuthenticationV1Interface
pubKeys []interface{} pubKeys []interface{}
x509Policy policy.X509NamePolicyEngine
sshPolicy policy.SSHNamePolicyEngine
} }
// GetID returns the provisioner unique identifier. The name and credential id // GetID returns the provisioner unique identifier. The name and credential id
@ -92,7 +95,7 @@ func (p *K8sSA) GetEncryptedKey() (string, string, bool) {
// Init initializes and validates the fields of a K8sSA type. // Init initializes and validates the fields of a K8sSA type.
func (p *K8sSA) Init(config Config) (err error) { func (p *K8sSA) Init(config Config) (err error) {
p.base = &base{} // prevent nil pointers
switch { switch {
case p.Type == "": case p.Type == "":
return errors.New("provisioner type cannot be empty") return errors.New("provisioner type cannot be empty")
@ -145,12 +148,12 @@ func (p *K8sSA) Init(config Config) (err error) {
} }
// Initialize the x509 allow/deny policy engine // Initialize the x509 allow/deny policy engine
if p.x509PolicyEngine, err = newX509PolicyEngine(p.Options.GetX509Options()); err != nil { if p.x509Policy, err = newX509PolicyEngine(p.Options.GetX509Options()); err != nil {
return err return err
} }
// Initialize the SSH allow/deny policy engine // Initialize the SSH allow/deny policy engine
if p.sshPolicyEngine, err = newSSHPolicyEngine(p.Options.GetSSHOptions()); err != nil { if p.sshPolicy, err = newSSHPolicyEngine(p.Options.GetSSHOptions()); err != nil {
return err return err
} }
@ -255,7 +258,7 @@ func (p *K8sSA) AuthorizeSign(ctx context.Context, token string) ([]SignOption,
// validators // validators
defaultPublicKeyValidator{}, defaultPublicKeyValidator{},
newValidityValidator(p.claimer.MinTLSCertDuration(), p.claimer.MaxTLSCertDuration()), newValidityValidator(p.claimer.MinTLSCertDuration(), p.claimer.MaxTLSCertDuration()),
newX509NamePolicyValidator(p.x509PolicyEngine), newX509NamePolicyValidator(p.x509Policy),
}, nil }, nil
} }
@ -302,7 +305,7 @@ func (p *K8sSA) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOptio
// Require and validate all the default fields in the SSH certificate. // Require and validate all the default fields in the SSH certificate.
&sshCertDefaultValidator{}, &sshCertDefaultValidator{},
// Ensure that all principal names are allowed // Ensure that all principal names are allowed
newSSHNamePolicyValidator(p.sshPolicyEngine), newSSHNamePolicyValidator(p.sshPolicy),
), nil ), nil
} }

View file

@ -11,6 +11,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
nebula "github.com/slackhq/nebula/cert" nebula "github.com/slackhq/nebula/cert"
"github.com/smallstep/certificates/errs" "github.com/smallstep/certificates/errs"
"github.com/smallstep/certificates/policy"
"go.step.sm/crypto/jose" "go.step.sm/crypto/jose"
"go.step.sm/crypto/sshutil" "go.step.sm/crypto/sshutil"
"go.step.sm/crypto/x25519" "go.step.sm/crypto/x25519"
@ -35,20 +36,21 @@ const (
// go.step.sm/crypto/x25519. // go.step.sm/crypto/x25519.
type Nebula struct { type Nebula struct {
*base *base
ID string `json:"-"` ID string `json:"-"`
Type string `json:"type"` Type string `json:"type"`
Name string `json:"name"` Name string `json:"name"`
Roots []byte `json:"roots"` Roots []byte `json:"roots"`
Claims *Claims `json:"claims,omitempty"` Claims *Claims `json:"claims,omitempty"`
Options *Options `json:"options,omitempty"` Options *Options `json:"options,omitempty"`
claimer *Claimer claimer *Claimer
caPool *nebula.NebulaCAPool caPool *nebula.NebulaCAPool
audiences Audiences audiences Audiences
x509Policy policy.X509NamePolicyEngine
sshPolicy policy.SSHNamePolicyEngine
} }
// Init verifies and initializes the Nebula provisioner. // Init verifies and initializes the Nebula provisioner.
func (p *Nebula) Init(config Config) error { func (p *Nebula) Init(config Config) error {
p.base = &base{} // prevent nil pointers
switch { switch {
case p.Type == "": case p.Type == "":
return errors.New("provisioner type cannot be empty") return errors.New("provisioner type cannot be empty")
@ -71,12 +73,12 @@ func (p *Nebula) Init(config Config) error {
p.audiences = config.Audiences.WithFragment(p.GetIDForToken()) p.audiences = config.Audiences.WithFragment(p.GetIDForToken())
// Initialize the x509 allow/deny policy engine // Initialize the x509 allow/deny policy engine
if p.x509PolicyEngine, err = newX509PolicyEngine(p.Options.GetX509Options()); err != nil { if p.x509Policy, err = newX509PolicyEngine(p.Options.GetX509Options()); err != nil {
return err return err
} }
// Initialize the SSH allow/deny policy engine // Initialize the SSH allow/deny policy engine
if p.sshPolicyEngine, err = newSSHPolicyEngine(p.Options.GetSSHOptions()); err != nil { if p.sshPolicy, err = newSSHPolicyEngine(p.Options.GetSSHOptions()); err != nil {
return err return err
} }
@ -177,6 +179,7 @@ func (p *Nebula) AuthorizeSign(ctx context.Context, token string) ([]SignOption,
}, },
defaultPublicKeyValidator{}, defaultPublicKeyValidator{},
newValidityValidator(p.claimer.MinTLSCertDuration(), p.claimer.MaxTLSCertDuration()), newValidityValidator(p.claimer.MinTLSCertDuration(), p.claimer.MaxTLSCertDuration()),
newX509NamePolicyValidator(p.x509Policy),
}, nil }, nil
} }
@ -272,6 +275,8 @@ func (p *Nebula) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOpti
&sshCertValidityValidator{p.claimer}, &sshCertValidityValidator{p.claimer},
// Require all the fields in the SSH certificate // Require all the fields in the SSH certificate
&sshCertDefaultValidator{}, &sshCertDefaultValidator{},
// Ensure that all principal names are allowed
newSSHNamePolicyValidator(p.sshPolicy),
), nil ), nil
} }

View file

@ -13,6 +13,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/smallstep/certificates/errs" "github.com/smallstep/certificates/errs"
"github.com/smallstep/certificates/policy"
"go.step.sm/crypto/jose" "go.step.sm/crypto/jose"
"go.step.sm/crypto/sshutil" "go.step.sm/crypto/sshutil"
"go.step.sm/crypto/x509util" "go.step.sm/crypto/x509util"
@ -94,6 +95,8 @@ type OIDC struct {
keyStore *keyStore keyStore *keyStore
claimer *Claimer claimer *Claimer
getIdentityFunc GetIdentityFunc getIdentityFunc GetIdentityFunc
x509Policy policy.X509NamePolicyEngine
sshPolicy policy.SSHNamePolicyEngine
} }
func sanitizeEmail(email string) string { func sanitizeEmail(email string) string {
@ -154,7 +157,6 @@ func (o *OIDC) GetEncryptedKey() (kid, key string, ok bool) {
// Init validates and initializes the OIDC provider. // Init validates and initializes the OIDC provider.
func (o *OIDC) Init(config Config) (err error) { func (o *OIDC) Init(config Config) (err error) {
o.base = &base{} // prevent nil pointers
switch { switch {
case o.Type == "": case o.Type == "":
return errors.New("type cannot be empty") return errors.New("type cannot be empty")
@ -210,12 +212,12 @@ func (o *OIDC) Init(config Config) (err error) {
} }
// Initialize the x509 allow/deny policy engine // Initialize the x509 allow/deny policy engine
if o.x509PolicyEngine, err = newX509PolicyEngine(o.Options.GetX509Options()); err != nil { if o.x509Policy, err = newX509PolicyEngine(o.Options.GetX509Options()); err != nil {
return err return err
} }
// Initialize the SSH allow/deny policy engine // Initialize the SSH allow/deny policy engine
if o.sshPolicyEngine, err = newSSHPolicyEngine(o.Options.GetSSHOptions()); err != nil { if o.sshPolicy, err = newSSHPolicyEngine(o.Options.GetSSHOptions()); err != nil {
return err return err
} }
@ -375,7 +377,7 @@ func (o *OIDC) AuthorizeSign(ctx context.Context, token string) ([]SignOption, e
// validators // validators
defaultPublicKeyValidator{}, defaultPublicKeyValidator{},
newValidityValidator(o.claimer.MinTLSCertDuration(), o.claimer.MaxTLSCertDuration()), newValidityValidator(o.claimer.MinTLSCertDuration(), o.claimer.MaxTLSCertDuration()),
newX509NamePolicyValidator(o.x509PolicyEngine), newX509NamePolicyValidator(o.x509Policy),
}, nil }, nil
} }
@ -466,7 +468,7 @@ func (o *OIDC) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption
// Require all the fields in the SSH certificate // Require all the fields in the SSH certificate
&sshCertDefaultValidator{}, &sshCertDefaultValidator{},
// Ensure that all principal names are allowed // Ensure that all principal names are allowed
newSSHNamePolicyValidator(o.sshPolicyEngine), newSSHNamePolicyValidator(o.sshPolicy),
), nil ), nil
} }

View file

@ -12,7 +12,6 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/smallstep/certificates/db" "github.com/smallstep/certificates/db"
"github.com/smallstep/certificates/errs" "github.com/smallstep/certificates/errs"
"github.com/smallstep/certificates/policy"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
) )
@ -305,10 +304,7 @@ func SanitizeSSHUserPrincipal(email string) string {
}, strings.ToLower(email)) }, strings.ToLower(email))
} }
type base struct { type base struct{}
x509PolicyEngine policy.X509NamePolicyEngine
sshPolicyEngine policy.SSHNamePolicyEngine
}
// AuthorizeSign returns an unimplemented error. Provisioners should overwrite // AuthorizeSign returns an unimplemented error. Provisioners should overwrite
// this method if they will support authorizing tokens for signing x509 Certificates. // this method if they will support authorizing tokens for signing x509 Certificates.

View file

@ -5,6 +5,7 @@ import (
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/smallstep/certificates/policy"
) )
// SCEP is the SCEP provisioner type, an entity that can authorize the // SCEP is the SCEP provisioner type, an entity that can authorize the
@ -19,11 +20,11 @@ type SCEP struct {
ChallengePassword string `json:"challenge,omitempty"` ChallengePassword string `json:"challenge,omitempty"`
Capabilities []string `json:"capabilities,omitempty"` Capabilities []string `json:"capabilities,omitempty"`
// MinimumPublicKeyLength is the minimum length for public keys in CSRs // MinimumPublicKeyLength is the minimum length for public keys in CSRs
MinimumPublicKeyLength int `json:"minimumPublicKeyLength,omitempty"` MinimumPublicKeyLength int `json:"minimumPublicKeyLength,omitempty"`
Options *Options `json:"options,omitempty"` Options *Options `json:"options,omitempty"`
Claims *Claims `json:"claims,omitempty"` Claims *Claims `json:"claims,omitempty"`
claimer *Claimer claimer *Claimer
x509Policy policy.X509NamePolicyEngine
secretChallengePassword string secretChallengePassword string
} }
@ -74,7 +75,6 @@ func (s *SCEP) DefaultTLSCertDuration() time.Duration {
// Init initializes and validates the fields of a SCEP type. // Init initializes and validates the fields of a SCEP type.
func (s *SCEP) Init(config Config) (err error) { func (s *SCEP) Init(config Config) (err error) {
s.base = &base{} // prevent nil pointers
switch { switch {
case s.Type == "": case s.Type == "":
return errors.New("provisioner type cannot be empty") return errors.New("provisioner type cannot be empty")
@ -103,7 +103,7 @@ func (s *SCEP) Init(config Config) (err error) {
// TODO: add other, SCEP specific, options? // TODO: add other, SCEP specific, options?
// Initialize the x509 allow/deny policy engine // Initialize the x509 allow/deny policy engine
if s.x509PolicyEngine, err = newX509PolicyEngine(s.Options.GetX509Options()); err != nil { if s.x509Policy, err = newX509PolicyEngine(s.Options.GetX509Options()); err != nil {
return err return err
} }
@ -122,7 +122,7 @@ func (s *SCEP) AuthorizeSign(ctx context.Context, token string) ([]SignOption, e
// validators // validators
newPublicKeyMinimumLengthValidator(s.MinimumPublicKeyLength), newPublicKeyMinimumLengthValidator(s.MinimumPublicKeyLength),
newValidityValidator(s.claimer.MinTLSCertDuration(), s.claimer.MaxTLSCertDuration()), newValidityValidator(s.claimer.MinTLSCertDuration(), s.claimer.MaxTLSCertDuration()),
newX509NamePolicyValidator(s.x509PolicyEngine), newX509NamePolicyValidator(s.x509Policy),
}, nil }, nil
} }

View file

@ -454,7 +454,6 @@ type sshNamePolicyValidator struct {
// newSSHNamePolicyValidator return a new SSH allow/deny validator. // newSSHNamePolicyValidator return a new SSH allow/deny validator.
func newSSHNamePolicyValidator(engine policy.SSHNamePolicyEngine) *sshNamePolicyValidator { func newSSHNamePolicyValidator(engine policy.SSHNamePolicyEngine) *sshNamePolicyValidator {
return &sshNamePolicyValidator{ return &sshNamePolicyValidator{
// TODO: should we use two engines, one for host certs; another for user certs?
policyEngine: engine, policyEngine: engine,
} }
} }
@ -465,7 +464,6 @@ func (v *sshNamePolicyValidator) Valid(cert *ssh.Certificate, _ SignSSHOptions)
if v.policyEngine == nil { if v.policyEngine == nil {
return nil return nil
} }
_, err := v.policyEngine.ArePrincipalsAllowed(cert) _, err := v.policyEngine.ArePrincipalsAllowed(cert)
return err return err
} }

View file

@ -84,7 +84,6 @@ func (p *SSHPOP) GetEncryptedKey() (string, string, bool) {
// Init initializes and validates the fields of a SSHPOP type. // Init initializes and validates the fields of a SSHPOP type.
func (p *SSHPOP) Init(config Config) error { func (p *SSHPOP) Init(config Config) error {
p.base = &base{} // prevent nil pointers
switch { switch {
case p.Type == "": case p.Type == "":
return errors.New("provisioner type cannot be empty") return errors.New("provisioner type cannot be empty")

View file

@ -177,7 +177,6 @@ func generateJWK() (*JWK, error) {
return nil, err return nil, err
} }
return &JWK{ return &JWK{
base: &base{},
Name: name, Name: name,
Type: "JWK", Type: "JWK",
Key: &public, Key: &public,
@ -216,7 +215,6 @@ func generateK8sSA(inputPubKey interface{}) (*K8sSA, error) {
} }
return &K8sSA{ return &K8sSA{
base: &base{},
Name: K8sSAName, Name: K8sSAName,
Type: "K8sSA", Type: "K8sSA",
Claims: &globalProvisionerClaims, Claims: &globalProvisionerClaims,
@ -254,7 +252,6 @@ func generateSSHPOP() (*SSHPOP, error) {
} }
return &SSHPOP{ return &SSHPOP{
base: &base{},
Name: name, Name: name,
Type: "SSHPOP", Type: "SSHPOP",
Claims: &globalProvisionerClaims, Claims: &globalProvisionerClaims,
@ -309,7 +306,6 @@ M46l92gdOozT
rootPool.AddCert(cert) rootPool.AddCert(cert)
} }
return &X5C{ return &X5C{
base: &base{},
Name: name, Name: name,
Type: "X5C", Type: "X5C",
Roots: root, Roots: root,
@ -342,7 +338,6 @@ func generateOIDC() (*OIDC, error) {
return nil, err return nil, err
} }
return &OIDC{ return &OIDC{
base: &base{},
Name: name, Name: name,
Type: "OIDC", Type: "OIDC",
ClientID: clientID, ClientID: clientID,
@ -378,7 +373,6 @@ func generateGCP() (*GCP, error) {
return nil, err return nil, err
} }
return &GCP{ return &GCP{
base: &base{},
Type: "GCP", Type: "GCP",
Name: name, Name: name,
ServiceAccounts: []string{serviceAccount}, ServiceAccounts: []string{serviceAccount},
@ -415,7 +409,6 @@ func generateAWS() (*AWS, error) {
return nil, errors.Wrap(err, "error parsing AWS certificate") return nil, errors.Wrap(err, "error parsing AWS certificate")
} }
return &AWS{ return &AWS{
base: &base{},
Type: "AWS", Type: "AWS",
Name: name, Name: name,
Accounts: []string{accountID}, Accounts: []string{accountID},
@ -525,7 +518,6 @@ func generateAWSV1Only() (*AWS, error) {
return nil, errors.Wrap(err, "error parsing AWS certificate") return nil, errors.Wrap(err, "error parsing AWS certificate")
} }
return &AWS{ return &AWS{
base: &base{},
Type: "AWS", Type: "AWS",
Name: name, Name: name,
Accounts: []string{accountID}, Accounts: []string{accountID},
@ -617,7 +609,6 @@ func generateAzure() (*Azure, error) {
return nil, err return nil, err
} }
return &Azure{ return &Azure{
base: &base{},
Type: "Azure", Type: "Azure",
Name: name, Name: name,
TenantID: tenantID, TenantID: tenantID,

View file

@ -9,6 +9,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/smallstep/certificates/errs" "github.com/smallstep/certificates/errs"
"github.com/smallstep/certificates/policy"
"go.step.sm/crypto/jose" "go.step.sm/crypto/jose"
"go.step.sm/crypto/sshutil" "go.step.sm/crypto/sshutil"
"go.step.sm/crypto/x509util" "go.step.sm/crypto/x509util"
@ -26,15 +27,17 @@ type x5cPayload struct {
// signature requests. // signature requests.
type X5C struct { type X5C struct {
*base *base
ID string `json:"-"` ID string `json:"-"`
Type string `json:"type"` Type string `json:"type"`
Name string `json:"name"` Name string `json:"name"`
Roots []byte `json:"roots"` Roots []byte `json:"roots"`
Claims *Claims `json:"claims,omitempty"` Claims *Claims `json:"claims,omitempty"`
Options *Options `json:"options,omitempty"` Options *Options `json:"options,omitempty"`
claimer *Claimer claimer *Claimer
audiences Audiences audiences Audiences
rootPool *x509.CertPool rootPool *x509.CertPool
x509Policy policy.X509NamePolicyEngine
sshPolicy policy.SSHNamePolicyEngine
} }
// GetID returns the provisioner unique identifier. The name and credential id // GetID returns the provisioner unique identifier. The name and credential id
@ -87,7 +90,6 @@ func (p *X5C) GetEncryptedKey() (string, string, bool) {
// Init initializes and validates the fields of a X5C type. // Init initializes and validates the fields of a X5C type.
func (p *X5C) Init(config Config) error { func (p *X5C) Init(config Config) error {
p.base = &base{} // prevent nil pointers
switch { switch {
case p.Type == "": case p.Type == "":
return errors.New("provisioner type cannot be empty") return errors.New("provisioner type cannot be empty")
@ -127,12 +129,12 @@ func (p *X5C) Init(config Config) error {
} }
// Initialize the x509 allow/deny policy engine // Initialize the x509 allow/deny policy engine
if p.x509PolicyEngine, err = newX509PolicyEngine(p.Options.GetX509Options()); err != nil { if p.x509Policy, err = newX509PolicyEngine(p.Options.GetX509Options()); err != nil {
return err return err
} }
// Initialize the SSH allow/deny policy engine // Initialize the SSH allow/deny policy engine
if p.sshPolicyEngine, err = newSSHPolicyEngine(p.Options.GetSSHOptions()); err != nil { if p.sshPolicy, err = newSSHPolicyEngine(p.Options.GetSSHOptions()); err != nil {
return err return err
} }
@ -240,7 +242,7 @@ func (p *X5C) AuthorizeSign(ctx context.Context, token string) ([]SignOption, er
defaultSANsValidator(claims.SANs), defaultSANsValidator(claims.SANs),
defaultPublicKeyValidator{}, defaultPublicKeyValidator{},
newValidityValidator(p.claimer.MinTLSCertDuration(), p.claimer.MaxTLSCertDuration()), newValidityValidator(p.claimer.MinTLSCertDuration(), p.claimer.MaxTLSCertDuration()),
newX509NamePolicyValidator(p.x509PolicyEngine), newX509NamePolicyValidator(p.x509Policy),
}, nil }, nil
} }
@ -324,6 +326,6 @@ func (p *X5C) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption,
// Require all the fields in the SSH certificate // Require all the fields in the SSH certificate
&sshCertDefaultValidator{}, &sshCertDefaultValidator{},
// Ensure that all principal names are allowed // Ensure that all principal names are allowed
newSSHNamePolicyValidator(p.sshPolicyEngine), newSSHNamePolicyValidator(p.sshPolicy),
), nil ), nil
} }