Add JWK provisioner to generic config.

Fix linter errors.
This commit is contained in:
Mariano Cano 2021-08-06 14:58:03 -07:00
parent 536536c92d
commit 47a30f1524
3 changed files with 64 additions and 37 deletions

View file

@ -163,7 +163,7 @@ func onboardAction(ctx *cli.Context) error {
} }
func onboardPKI(config onboardingConfiguration) (*config.Config, string, error) { func onboardPKI(config onboardingConfiguration) (*config.Config, string, error) {
var opts = []pki.PKIOption{ var opts = []pki.Option{
pki.WithAddress(config.Address), pki.WithAddress(config.Address),
pki.WithDNSNames([]string{config.DNS}), pki.WithDNSNames([]string{config.DNS}),
pki.WithProvisioner("admin"), pki.WithProvisioner("admin"),

View file

@ -6,14 +6,15 @@ import (
"github.com/Masterminds/sprig/v3" "github.com/Masterminds/sprig/v3"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/smallstep/certificates/authority"
authconfig "github.com/smallstep/certificates/authority/config" authconfig "github.com/smallstep/certificates/authority/config"
"github.com/smallstep/certificates/authority/provisioner" "github.com/smallstep/certificates/authority/provisioner"
"go.step.sm/linkedca" "go.step.sm/linkedca"
) )
type helmVariables struct { type helmVariables struct {
linkedca.Configuration *linkedca.Configuration
Defaults linkedca.Defaults Defaults *linkedca.Defaults
Password string Password string
SSH struct { SSH struct {
Enabled bool Enabled bool
@ -33,19 +34,22 @@ func (p *PKI) WriteHelmTemplate(w io.Writer) error {
p.Ssh = nil p.Ssh = nil
} }
// Convert provisioner to ca.json
provisioners := make([]provisioner.Interface, len(p.Authority.Provisioners))
for i, p := range p.Authority.Provisioners {
pp, err := authority.ProvisionerToCertificates(p)
if err != nil {
return err
}
provisioners[i] = pp
}
if err := tmpl.Execute(w, helmVariables{ if err := tmpl.Execute(w, helmVariables{
Configuration: p.Configuration, Configuration: &p.Configuration,
Defaults: p.Defaults, Defaults: &p.Defaults,
Password: "asdf", Password: "",
TLS: authconfig.DefaultTLSOptions, TLS: authconfig.DefaultTLSOptions,
Provisioners: []provisioner.Interface{ Provisioners: provisioners,
&provisioner.JWK{
Name: p.options.provisioner,
Type: "JWK",
Key: p.ottPublicKey,
EncryptedKey: "",
},
},
}); err != nil { }); err != nil {
return errors.Wrap(err, "error executing helm template") return errors.Wrap(err, "error executing helm template")
} }

View file

@ -166,81 +166,81 @@ type options struct {
deploymentType DeploymentType deploymentType DeploymentType
} }
// PKIOption is the type of a configuration option on the pki constructor. // Option is the type of a configuration option on the pki constructor.
type PKIOption func(p *PKI) type Option func(p *PKI)
// WithAddress sets the listen address of step-ca. // WithAddress sets the listen address of step-ca.
func WithAddress(s string) PKIOption { func WithAddress(s string) Option {
return func(p *PKI) { return func(p *PKI) {
p.Address = s p.Address = s
} }
} }
// WithCaUrl sets the default ca-url of step-ca. // WithCaURL sets the default ca-url of step-ca.
func WithCaUrl(s string) PKIOption { func WithCaURL(s string) Option {
return func(p *PKI) { return func(p *PKI) {
p.Defaults.CaUrl = s p.Defaults.CaUrl = s
} }
} }
// WithDNSNames sets the SANs of step-ca. // WithDNSNames sets the SANs of step-ca.
func WithDNSNames(s []string) PKIOption { func WithDNSNames(s []string) Option {
return func(p *PKI) { return func(p *PKI) {
p.DnsNames = s p.DnsNames = s
} }
} }
// WithProvisioner defines the name of the default provisioner. // WithProvisioner defines the name of the default provisioner.
func WithProvisioner(s string) PKIOption { func WithProvisioner(s string) Option {
return func(p *PKI) { return func(p *PKI) {
p.options.provisioner = s p.options.provisioner = s
} }
} }
// WithPKIOnly will only generate the PKI without the step-ca config files. // WithPKIOnly will only generate the PKI without the step-ca config files.
func WithPKIOnly() PKIOption { func WithPKIOnly() Option {
return func(p *PKI) { return func(p *PKI) {
p.options.pkiOnly = true p.options.pkiOnly = true
} }
} }
// WithACME enables acme provisioner in step-ca. // WithACME enables acme provisioner in step-ca.
func WithACME() PKIOption { func WithACME() Option {
return func(p *PKI) { return func(p *PKI) {
p.options.enableACME = true p.options.enableACME = true
} }
} }
// WithSSH enables ssh in step-ca. // WithSSH enables ssh in step-ca.
func WithSSH() PKIOption { func WithSSH() Option {
return func(p *PKI) { return func(p *PKI) {
p.options.enableSSH = true p.options.enableSSH = true
} }
} }
// WithAdmin enables the admin api in step-ca. // WithAdmin enables the admin api in step-ca.
func WithAdmin() PKIOption { func WithAdmin() Option {
return func(p *PKI) { return func(p *PKI) {
p.options.enableAdmin = true p.options.enableAdmin = true
} }
} }
// WithNoDB disables the db in step-ca. // WithNoDB disables the db in step-ca.
func WithNoDB() PKIOption { func WithNoDB() Option {
return func(p *PKI) { return func(p *PKI) {
p.options.noDB = true p.options.noDB = true
} }
} }
// WithHelm configures the pki to create a helm values.yaml. // WithHelm configures the pki to create a helm values.yaml.
func WithHelm() PKIOption { func WithHelm() Option {
return func(p *PKI) { return func(p *PKI) {
p.options.isHelm = true p.options.isHelm = true
} }
} }
// WithDeploymentType defines the deployment type of step-ca. // WithDeploymentType defines the deployment type of step-ca.
func WithDeploymentType(dt DeploymentType) PKIOption { func WithDeploymentType(dt DeploymentType) Option {
return func(p *PKI) { return func(p *PKI) {
p.options.deploymentType = dt p.options.deploymentType = dt
} }
@ -261,7 +261,7 @@ type PKI struct {
} }
// New creates a new PKI configuration. // New creates a new PKI configuration.
func New(o apiv1.Options, opts ...PKIOption) (*PKI, error) { func New(o apiv1.Options, opts ...Option) (*PKI, error) {
caService, err := cas.New(context.Background(), o) caService, err := cas.New(context.Background(), o)
if err != nil { if err != nil {
return nil, err return nil, err
@ -287,6 +287,7 @@ func New(o apiv1.Options, opts ...PKIOption) (*PKI, error) {
Address: "127.0.0.1:9000", Address: "127.0.0.1:9000",
DnsNames: []string{"127.0.0.1"}, DnsNames: []string{"127.0.0.1"},
Ssh: &linkedca.SSH{}, Ssh: &linkedca.SSH{},
Authority: &linkedca.Authority{},
Files: make(map[string][]byte), Files: make(map[string][]byte),
}, },
casOptions: o, casOptions: o,
@ -395,6 +396,28 @@ func (p *PKI) GenerateKeyPairs(pass []byte) error {
return err return err
} }
// Add JWK provisioner to the configuration.
publicKey, err := json.Marshal(p.ottPublicKey)
if err != nil {
return errors.Wrap(err, "error marshaling public key")
}
encryptedKey, err := p.ottPrivateKey.CompactSerialize()
if err != nil {
return errors.Wrap(err, "error serializing private key")
}
p.Authority.Provisioners = append(p.Authority.Provisioners, &linkedca.Provisioner{
Type: linkedca.Provisioner_JWK,
Name: p.options.provisioner,
Details: &linkedca.ProvisionerDetails{
Data: &linkedca.ProvisionerDetails_JWK{
JWK: &linkedca.JWKProvisioner{
PublicKey: publicKey,
EncryptedPrivateKey: []byte(encryptedKey),
},
},
},
})
return nil return nil
} }
@ -593,11 +616,11 @@ type caDefaults struct {
Root string `json:"root"` Root string `json:"root"`
} }
// Option is the type for modifiers over the auth config object. // ConfigOption is the type for modifiers over the auth config object.
type Option func(c *authconfig.Config) error type ConfigOption func(c *authconfig.Config) error
// GenerateConfig returns the step certificates configuration. // GenerateConfig returns the step certificates configuration.
func (p *PKI) GenerateConfig(opt ...Option) (*authconfig.Config, error) { func (p *PKI) GenerateConfig(opt ...ConfigOption) (*authconfig.Config, error) {
var authorityOptions *apiv1.Options var authorityOptions *apiv1.Options
if !p.casOptions.Is(apiv1.SoftCAS) { if !p.casOptions.Is(apiv1.SoftCAS) {
authorityOptions = &p.casOptions authorityOptions = &p.casOptions
@ -726,7 +749,7 @@ func (p *PKI) GenerateConfig(opt ...Option) (*authconfig.Config, error) {
// Save stores the pki on a json file that will be used as the certificate // Save stores the pki on a json file that will be used as the certificate
// authority configuration. // authority configuration.
func (p *PKI) Save(opt ...Option) error { func (p *PKI) Save(opt ...ConfigOption) error {
// Write generated files // Write generated files
if err := p.WriteFiles(); err != nil { if err := p.WriteFiles(); err != nil {
return err return err